{"action":"closed","issue":{"url":"https://api.github.com/repos/NancyFx/Nancy/issues/2126","labels_url":"https://api.github.com/repos/NancyFx/Nancy/issues/2126/labels{/name}","comments_url":"https://api.github.com/repos/NancyFx/Nancy/issues/2126/comments","events_url":"https://api.github.com/repos/NancyFx/Nancy/issues/2126/events","html_url":"https://github.com/NancyFx/Nancy/issues/2126","id":118359617,"number":2126,"title":"Testing a custom bootstrapper","user":{"login":"alexsaare","id":4030796,"avatar_url":"https://avatars.githubusercontent.com/u/4030796?v=3","gravatar_id":"","url":"https://api.github.com/users/alexsaare","html_url":"https://github.com/alexsaare","followers_url":"https://api.github.com/users/alexsaare/followers","following_url":"https://api.github.com/users/alexsaare/following{/other_user}","gists_url":"https://api.github.com/users/alexsaare/gists{/gist_id}","starred_url":"https://api.github.com/users/alexsaare/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/alexsaare/subscriptions","organizations_url":"https://api.github.com/users/alexsaare/orgs","repos_url":"https://api.github.com/users/alexsaare/repos","events_url":"https://api.github.com/users/alexsaare/events{/privacy}","received_events_url":"https://api.github.com/users/alexsaare/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":13,"created_at":"2015-11-23T11:07:46Z","updated_at":"2015-12-09T15:45:40Z","closed_at":"2015-12-09T15:45:40Z","body":"Hi,  I raised this stackoverflow question\r\n\r\nhttp://stackoverflow.com/questions/33830206/testing-code-in-a-custom-nancyfx-bootstrapper/3386149\r\n\r\nFor completeness I'll repeat the custom bootstrapper here\r\n\r\n    public class CustomNancyBootstrapper : StructureMapNancyBootstrapper\r\n    {\r\n        protected override void RequestStartup(IContainer container, IPipelines pipelines, NancyContext context)\r\n        {\r\n            var auth = container.GetInstance<ICustomAuth>();\r\n            auth.Authenticate(context);\r\n        }\r\n    }  \r\n\r\nI want to write a test to assert that Authenticate is called with the context.\r\n\r\nThe issue is the same regardless of container.  \r\n\r\nAs far as i can see you are faced with either 2 options\r\n1 - Derive another class from your own custom bootstrapper which has a public method which calls the protected method... not great but the test is fairly concise easy to read.\r\n\r\n    [Test]\r\n    public void RequestStartup_Calls_CustomAuth_Authenticate_WithContext()\r\n    {\r\n        // set up\r\n        var mockAuthentication = new Mock<ICustomAuth>();\r\n        var mockContainer = new Mock<IContainer>();\r\n        var mockPipelines = new Mock<IPipelines>();\r\n        var context = new NancyContext();\r\n\r\n        mockContainer.Setup(x => x.GetInstance<ICustomAuth>()).Returns(mockAuthentication.Object);\r\n\r\n        var bootstrapper = new CustomNancyBootstrapperWrapper()\r\n\r\n        // exercise\r\n        bootstrapper.RequestStartupPublic(_mockContainer.Object, _mockPipelines.Object, context);\r\n\r\n        // verify\r\n        mockAuthentication.Verify(x => x.Authenticate(context), Times.Once);\r\n    }\r\n\r\n    private class CustomNancyBootstrapperWrapper : CustomNancyBootstrapper \r\n    {\r\n        public void RequestStartupPublic(IContainer container, IPipelines pipelines, NancyContext context)\r\n        {\r\n            RequestStartup(container, pipelines, context);\r\n        }\r\n    }\r\n\r\n2 - Use the Browser offered in Nancy.Testing however, this is really testing the route/module and only testing the bootstrapper indirectly. This is very difficult to read and it's very brittle...\r\n\r\n        [Test]\r\n        public void When_Route_Is_Requested_Bootstrapper_Calls_Authenticate_Via_RequestStartup()\r\n        {\r\n            var mockAuthentication = new Mock<ICustomAuth>();\r\n\r\n            var container = ContainerWrapper.Instance;\r\n\r\n            container.Configure(c =>\r\n            {\r\n                c.For<ICustomAuth>().Use(() => mockAuthentication.Object);\r\n            });\r\n\r\n            var browser = new Browser(new CustomNancyBootstrapper());\r\n\r\n            // exercise\r\n            browser.Get(\"/\");\r\n            \r\n            // verify\r\n            mockAuthentication.Verify(x => x.Authenticate(It.IsAny<NancyContext>()), Times.Once);\r\n        }\r\n\r\nAlso, note.. there's no way to test that a specific NancyContext was used and you have to resort to\r\n\r\n      It.IsAny<NancyContext>()\r\n\r\nSo If I change my bootstrapper to this...  \r\n\r\n    public class CustomNancyBootstrapper : StructureMapNancyBootstrapper\r\n    {\r\n        protected override void RequestStartup(IContainer container, IPipelines pipelines, NancyContext context)\r\n        {\r\n            var auth = container.GetInstance<ICustomAuth>();\r\n            auth.Authenticate(new NancyContext());\r\n        }\r\n    }  \r\n\r\nMy test still passes but my application wouldn't work... making my test pretty much pointless.\r\n\r\nAny thoughts on testing a custom bootstrapper more explicitly would be appreciated. What is the benefit of these methods being protected?  Given NancyBootStrapperBase<TContainer> is abstract, any derived types will contain code which should be tested.  The protected modifiers really make that really difficult.  \r\n"}}