Integration testing in-memory WebAPI with Autofac

Continuing on my previous post on WebAPI, Autofac and filters, I now want to add an integration test.

Unit testing WebAPI controllers is no different than testing other pieces of code. Just inject mocks in the constructor and you're good to go.

Integration testing can be as simple, if you're not using filters. The filters can, however, add interesting behavior to your controllers, like the exception handling I explained in my previous post.

To fully test this, you will have to host your WebAPI in memory. Googling around will most probably lead you to this post by Kiran Challa. However, that doesn't factor in Autofac.

To do that, we need some extra steps.

InMemoryHttpContentSerializationHandler

First, copy over the InMemoryHttpContentSerializationHandler from Kiran Challa's post. Kiran explains very nicely why we use this class.

Server

Creating the server is a little different than in Kiran's post, because we need to add Autofac to the mix:

var config = new HttpConfiguration();
WebApiConfig.Register(config);
AutofacConfig.Register(config);
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

var server = new HttpServer(config);

Configuration

The WebApiConfig you see above is where we set up our routes. This is no different than what you do at runtime.

The AutofacConfig is the interesting part. Instead of following the Autofac documentation, where you grab the HttpConfiguration from the GlobalConfiguration, we inject it.

This is to avoid the error stating This method cannot be called during the application's pre-start initialization phase.

The Autofac configuration will look like this:

public static void Register(HttpConfiguration config)
{
    var builder = new ContainerBuilder();

    // Register your Web API controllers.
    builder.RegisterAssemblyModules(
        typeof(DependencyInjectionConfig).Assembly);

    // OPTIONAL: Register the Autofac filter provider.
    builder.RegisterWebApiFilterProvider(config);

    // Set the dependency resolver to be Autofac.
    var container = builder.Build();
    config.DependencyResolver 
        = new AutofacWebApiDependencyResolver(container);
}

In your integration test, this allows you to inject your own HttpConfiguration, while at runtime, we use the GlobalConfiguration:

GlobalConfiguration.Configure(AutofacConfig.Register);

Etcetera

Now you can continue with the test, just like Kiran explains:

var client = new HttpClient(
    new InMemoryHttpContentSerializationHandler(server));

var request = new HttpRequestMessage();
// ... set up request

using (var response = client.SendAsync(request).Result)
{
    // Assert your response
}

Conclusion

It's entirely possible to run an integration test on in-memory WebAPI with Autofac, but it takes some modifications. If you can't get it to work, let me know. You can contact me via Twitter (I've yet to set up some comments-system on my blog).