Juri Strumpflohner
Juri Strumpflohner Juri is a full stack developer and tech lead with a special passion for the web and frontend development. He creates online videos for Egghead.io, writes articles on his blog and for tech magazines, speaks at conferences and holds training workshops. Juri is also a recognized Google Developer Expert in Web Technologies

Writing IoC Supported Integration Tests using AutoFac

2 min read

Using a dependency injection framework can greatly facilitate your code's testability in that you don't have any "glue" code for managing a classes' dependency that needs to be mocked (if even possible) when writing unit tests. But what about when writing integration tests? In such case you'd probably want to use your IoC container's configuration for resolving types in order to also verify the proper integration of your components, frankly your dependency injection configuration, right?

With AutoFac it is actually quite simple. What your integration test needs to do is to himself create the ContainerBuilder() and accordingly register the dependencies. What you should do is the following. Assume you have a Visual Studio project that encapsulates your business logic called "BusinessLogic". Then the best strategy is to create a so-called Autofac module per project (and hence dll) to configure the dependencies within that specific project. This is done by extending the abstract class Autofac.Module like
public class BusinessLogicModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//register other modules/dependencies here
}
}

When you now want to write a test for the BusinessLogic project, you might create a BusinessLogic.IntegrationTests project, adding the project under test as a reference.
A possible approach to this could be the following: create ageneric class for instantiating the Autofac IoC container with the BusinessLogicModule created before. Let's call this class "IoCSupportedTest":
using Autofac;
using Autofac.Core;

namespace BusinessLogic.IntegrationTest.Utils
{
public class IoCSupportedTest<TModule> where TModule : IModule, new()
{
private IContainer container;

public IoCSupportedTest()
{
var builder = new ContainerBuilder();

builder.RegisterModule(new TModule());

container = builder.Build();
}

protected TEntity Resolve<TEntity>()
{
return container.Resolve<TEntity>();
}

protected void ShutdownIoC()
{
container.Dispose();
}
}
}
A specific test case might then look as follows:
[TestClass]
public class UserRepositoryTest : IoCSupportedTest<BusinessLogicModule>
{
private IUserRepository userRepo;

[TestInitialize]
public void Setup()
{
this.userRepo = Resolve<IUserRepository>();
}

[TestCleanup]
public void TearDown()
{
userRepo = null;
ShutdownIoC();
}

//the tests
}


Questions? Thoughts? Hit me up on Twitter
comments powered by Disqus