What should be the strategy of unit testing when using IoC?

Tomas Vana picture Tomas Vana · Feb 21, 2010 · Viewed 8.3k times · Source

After all what I have read about Dependency Injection and IoC I have decided to try to use Windsor Container within our application (it's a 50K LOC multi-layer web app, so I hope it's not an overkill there). I have used a simple static class for wrapping the container and I initialize it when starting the app, which works quite fine for now.

My question is about unit testing. I know that DI is going to make my life much easier there by giving me the possibility of injecting stub / mock implementations of class collaborators to the class under test. I have already written a couple of tests using this technique and it seems to make sense for me. What I am not sure about is whether I should be using IoC (in this case Windsor Castle) also in unit tests (probably somehow configure it to return stubs / mocks for my special cases) or is it better to wire-up all the dependencies manually in the tests. What do you think and what practice has worked for you ?

Answer

Darin Dimitrov picture Darin Dimitrov · Feb 21, 2010

You don't need DI container in unit tests because dependencies are provided through mock objects generated with frameworks such as Rhino Mocks or Moq. So for example when you are testing a class that has a dependency on some interface this dependency is usually provided through constructor injection.

public class SomeClassToTest
{
    private readonly ISomeDependentObject _dep;
    public SomeClassToTest(ISomeDependentObject dep)
    {
        _dep = dep;
    }

    public int SomeMethodToTest()
    {
        return _dep.Method1() + _dep.Method2();
    }
}

In your application you will use a DI framework to pass some real implementation of ISomeDependentObject in the constructor which could itself have dependencies on other objects while in a unit test you create a mock object because you only want to test this class in isolation. Example with Rhino Mocks:

[TestMethod]
public void SomeClassToTest_SomeMethodToTest()
{
    // arrange
    var depStub = MockRepository.CreateStub<ISomeDependentObject>();
    var sut = new SomeClassToTest(depStub);
    depStub.Stub(x => x.Method1()).Return(1);
    depStub.Stub(x => x.Method2()).Return(2);

    // act
    var actual = sut.SomeMethodToTest();

    // assert
    Assert.AreEqual(3, actual);
}