2
votes

so I think I'm perhaps not fully understanding how you would use an IOC container for doing Integration tests.

Let's assume I have a couple of classes:

public class EmailComposer : IComposer
{
    public EmailComposer(IEmailFormatter formatter)
    {
        ...
    }
    ...
    public string Write(string message)
    {
        ...
        return _formatter.Format(message);
    }
}

OK so for use during the real application (I'm using autofac here) I'd create a module and do something like:

    protected override void Load(ContainerBuilder containerBuilder)
    {
        containerBuilder.RegisterType<HtmlEmailFormatter>().As<IEmailFormatter>();
    }

Makes perfect sense and works great.

When it comes to Unit Tests I wouldn't use the IOC container at all and would just mock out the formatter when I'm doing my tests. Again works great.

OK now when it comes to my integration tests... Ideally I'd be running the full stack during integration tests obviously, but let's pretend the HtmlEmailFormatter is some slow external WebService so I decide it's in my best interest to use a Test Double instead. But... I don't want to use the Test Double on all of my integration tests, just a subset (a set of smoke-test style tests that are quick to run).

At this point I want to inject a mock version of the webservice, so that I can validate the correct methods were still called on it.

So, the real question is:

If I have a class with a constructor that takes in multiple parameters, how do I make one of the parameters resolve to a an instance of an object (i.e. the correctly setup Mock) but the rest get populated by autofac?

1
I would say that for integration tests the same holds as for unit tests: don't use the DI container, instantiate your objects manually (perhaps with some help of factory methods placed in your integration test suite).Steven

1 Answers

1
votes

I would say you use the SetUp and TearDown (NUnit) or ClassInitialize and ClassCleanup (MSTest) for this. In initialize you register your temporary test class and in cleanup you restore to normal state.

Having the DI container specify all the dependencies for you has the benefit of getting an entire object graph of dependencies resolved. However if there's a single test in which you want to use a different implementation I would use a Mocking framework instead.