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 in the comments or via Twitter.