unit-testingasp.net-mvc-5owin

Create Unit Test for MVC 5 Controller with Owin


I am trying to create a unit test to run with the controllers that are included in the .NET template project for the MVC 5 in Visual Studio 2013 using Framework 4.5.1.

This was suppose to test the ManageController class included in the project for standard user login.

Here is the code I am using to call the Index action of the controller (remember that the "Index" action is the default one):

[TestClass]
public class ManageControllerTests {
    [TestMethod]
    public async Task ManageController_Index_ShoudlPass() {
        using (var server = TestServer.Create<Startup>()) {
            var response = await server.HttpClient.GetAsync("/Manage");
            Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
        }
    }
}

The test does not fail but the response is a 404. And if I try to debug the process does not seems to hit the Index method in the controller or event the controller constructor.

I've added the "Microsoft.Owin.Testing" package via NuGet. And the Configuration method in the Startup class of the application is being called correctly.

What am I missing? I could not find a clear example in the web to implement that test. Can some one put here a step by step on how to test that controller?

Thanks


Solution

  • You can not do that. OWIN pipeline is meant to run decoupled with any hosting env.

    MVC is strongly couple with system.web which makes it harder to test with OWIN pipeline.

    You can do something similar like this:

    [TestClass] 
    public class ManageControllerTests {
        [TestMethod]
        public async Task ManageController_Index_ShoudlPass() {
            using (var server = CustomTestServer.Create<Startup>()) {
                server.OnNextMiddleware = context =>
                {
                    context.Response.StatusCode.ShouldBe(Convert.ToInt16(HttpStatusCode.OK));
                    return Task.FromResult(0);
                }
                var response = await server.HttpClient.GetAsync("/Manage"); 
            }
        }
    

    You will need to derive

    public class CustomTestServer : TestServer
    

    And add the middleware in the constructor after your existing middleware

    appBuilder.Use(async (context, next) =>
        {
            await OnNextMiddleware(context);
        });
    

    And a public member

    public Func<IOwinContext, Task> OnNextMiddleware { get; set; }
    

    From there, when you call server.httpclient.getasync... the middleware will pass the response to next middleware to handle.