Integration testing ASP.NET 5 and ASP.NET MVC 6 applications

The other day I ran into a post by Alex Zeitler, who blogged about integration testing of ASP.NET MVC 6 controllers. Alex has done some great work for the Web API community in the past and I always enjoy his posts.

In this case, Alex suggested using self hosting for that, so spinning up a server and hitting it over HTTP and then shutting down, as part of each test case. Some people have done that in the past with Web API too, but is not an approach I agree with when doing integration testing. If you follow this blog you might have seen my post about testing OWIN apps and Web API apps in memory already.

My main issue with the self-host approach, is that you and up testing the underlying operating system networking stack, the so-called “wire” which is not necessarily something you want to test – given that it will be different anyway in production (especially if you intend to run on IIS). On the other hand, you want to be able to run end-to-end tests quickly anywhere – developer’s machine, integration server or any other place that it might be necessary, and doing it entirely in memory is a great approach.


In the past, to memory host a Web API application you’d use an HttpServer type, which was a part of the framework. To memory host an OWIN pipeline you could use Microsoft.Owin.Testing package or Damian Hickey’s OwinHttpMessageHandler.

In ASP.NET 5 (DNX world), Microsoft has produced a Nuget package called Microsoft.AspNet.TestHost which you can easily utilize to run your ASP.NET 5 in memory instead of over the wire.

In fact, the aforementioned OwinHttpMessageHandler is also DNX compatible now, but it operates on a lower sets of abstractions, such as AppFunc and MidFunc. However, if you are doing pure OWIN development, this is definitely something you’d want to check out.

On the other hand Microsoft.AspNet.TestHost allows you to plug in the Action<IApplicationBuilder> and Action<IServicesCollection> which will likely be already existing as part of your ASP.NET 5 Startup class.

Putting it together

To test an ASP.NET 5 application you will need the new XUnit.DNX integration packages and the Microsoft.AspNet.TestHost package. Here are my project.json dependencies (xunit Visual Studio integration for DNX projects is entirely contained in the *xunit.runner.dnx* package):

Next, let’s imagine a test controller and a default Startup class – of course in your application those will be much more complicated, but for illustration purposes the defaults that come with the MVC 6 project templates are enough. I also added a simple validation to one of the actions, just so that we have a code path with non-successful HTTP response code.

Microsoft.AspNet.TestHost.TestServer is the class that you will use, and it exposes a bunch of factory methods depending on how much set up you want to do:

The server is being created as http://localhost unless you set the BaseAddress property to something else (i.e. if you want https binding). The actual URL is not important and can be anything – as long as the server and client agree on the same value.

As mentioned before, the factory methods on the TestServer make it easy to integrate your Startup class into the tests.

Below is an example of the setup of tests:

All that’s left at this point is to simply create the instance of a TestServer in each individual test, pass in the delegates saved in the fields, and create an HttpClient off the server (TestServer exposes a method CreateClient). At that point, you use the instantiated HttpClient just like you are used to – except all interaction with the “server” happens in memory.

Below are a few example tests against our test controller shown earlier:

And the result:

Integration tests

In each of the above cases we are able to run robust end-to-end integration in a very fast way, without worrying about the network stack.

What’s worth mentioning is that all end-to-end tests in the MVC 6 repository use the same approach.