OWIN/Katana in-memory integration testing

A while ago we looked at testing the ASP.NET Web API pipeline using its in-memory hosting capabilities.

The advantages of such approach to end-to-end testing are unquestionable.

Now, with the emergence of OWIN as the primary hosting option for a wide array of web frameworks, it makes sense to explore how you could to the same, except in the OWIN (or rather Katana, since all the things shown here are Katana specific) context – so not just against Web API, but against any framework of your choice (running on top of OWIN & Katana).

Creating dummy app to test

Suppose you have a simple Owin app – in our case I’ll pull in Nancy and ASP.NET Web API and use them to create some testable endpoints.

We’ll need a dummy ApiController and a dummy NancyModule:

And, of course, this being an Owin/Katana app, let’s create a Startup class, where we configure the Web API routes and give it a priority over Nancy (the rationale is API routes should be more greedy):

Now we can proceed to writing integration tests for this.

Owin Integration tests

The easiest way to get started with OWIN integration tetsing is to install the Microsoft.Owin.Testing package from Nuget.

This will allow us to create an in-memory server, which will accept HTTP requests and issues HTTP responses without touching the network stack (entirely in process), which is both very efficient and extremely fast.

Note: if you do the tests in a different assembly from your web app (which I assume you do), and you use Web API or SignalR, you will need to add assembly binding redirects to your app.config). They are built with Microsoft.Owin 2.0.0 but the latest on Nuget is 2.0.2.

In these examples we will use nunit but of course any test framework of your preference is fine.

So what are we doing here? We spin up an instance of an in-memory test server per test fixture, and allow each test to use it to make HTTP calls through the OWIN pipeline. Then in the tear down, we get rid of it.

We can make calls to individual endpoints of our web application by simply using the HttpClient that hangs off the server, and consume it the same way as you would consume any HTTP service in .NET – and then perform the necessary asserts. By the way – the ReadAsAsync extension method comes from the Microsoft.AspNet.WebApi.Client Nuget package and is used here merely for deserialization convenience.

passedtests

If, for some reason, you don’t want to use the “built in” HttpClient property, you can instantiate your own HttpClient very easily:

In this case we create a test client with a dummy absolute BaseAddress (it’s mandatory) and pass in the HttpMessageHandler hanging off the TestServer to the client’s constructor. This syntax and approach to working with the client might be familiar to you, because that’s exactly how we worked with integration tetsing in the traditional ASP.NET Web API in-memory hosting.

Either way, initializing and working with the in memory server is extremely straight forward. You may prefer to isolate it entirely and initialize the test server in every unit test but as far as I am concerned, the per-fixture approach is fine too. In that case you would simply dispose it per test:

Interesting additional functionality is that you don’t even have to use your Startup class, as the entire config can be done inline using a lambda:

Have at it, my friends!