Use [TestInitialize] / [Setup] Attributes to Simplify Your Test Setup

If you have a class under test into which you are dependency injecting multiple (mocked) dependencies, you might have struggled with strategies for minimizing code duplication when creating your class under test along with its mocked dependencies:

[TestFixture]
public class MyTest
{
    [Test]
    public void Test1
    {
        // Arrange
        var myDependency1 = new Mock<IMyDependency1>();
        var myDependency2 = new Mock<IMyDependency2>();
        var myClassToTest = new MyClassToTest(myDependency1.Object, 
        myDependency2.Object);

        // Test code follows …
    }

[Test]
public void Test2
    {
        // Arrange
        var myDependency1 = new Mock<IMyDependency1>();
        var myDependency2 = new Mock<IMyDependency2>();
        var myClassToTest = new MyClassToTest(myDependency1.Object, 
        myDependency2.Object);

        // More test code follows …
    }
}

As you can see, the “Arrange” portion of your test code might contain substantial duplication. If you change the constructor signature of your class being tested, you might wind up fixing compilation errors all over the place.


One naïve method might be to try to use a Refactor -> Extract Method style of strategy, such as:

[TestFixture]
public class MyTest
{
    [Test]
    public void Test1
    {
        var myClassToTest = CreateClassToTest();

        // Test code follows …
    }

    [Test]
    public void Test2
    {
        var myClassToTest = CreateClassToTest();

        // More test code follows …
    }

    private MyClassToTest CreateClassToTest()
    {
        var myDependency1 = new Mock<IMyDependency1>();
        var myDependency2 = new Mock<IMyDependency2>();
        return new MyClassToTest(myDependency1.Object, myDependency2.Object);
    }
}

In this example, code duplication is reduced, however you’re left with the problem of your Mocks being out of scope from your actual test methods, so there is no way to perform any .Setup(x=> …) actions on them.


For the longest time I worked around this by changing the class fields holding reference to the dependencies inside of MyClassToTest from private to internal, and then using the InternalsVisibleTo assembly attribute to give my test project visibility to the internal members of classes within my project that was being tested. This meant that in a test method, I only needed to create instances of the mocked dependencies which that method itself actually required:

[TestFixture]
public class MyTest
{
    [Test]
    public void Test1
    {
        var myClassToTest = CreateClassToTest();
        var myDependency1 = new Mock<IMyDependency1>();
        myDependency1.Setup(x=> x.GetStuff).Returns(new List<Stuff>());
        myClassToTest.MyDependency1 = myDependency1.Object;

        // Test code follows …
    }

[Test]
public void Test2
{
    var myClassToTest = CreateClassToTest();
    var myDependency2 = new Mock<IMyDependency2>();
    myDependency2.Setup(x=> x.GetOtherStuff).Returns(new List<OtherStuff>());
    myClassToTest.MyDependency2 = myDependency2.Object;

    // More test code follows …
}

private MyClassToTest CreateClassToTest()
{
    var myDependency1 = new Mock<IMyDependency1>();
    var myDependency2 = new Mock<IMyDependency2>();
    return new MyClassToTest(myDependency1.Object, 
        myDependency2.Object);
}

}

Aside from the fact that I was constantly constantly forgetting to assign my mock’s .Object to the property exposed by the class under test, this example can be improved on considerably. It is starting to get cluttered, and I’ve always felt that the whole InternalsVisibleTo trick was a bit of an encapsulation violation.


[TestFixture]
public class MyTest
{
    private Mock<IMyDependency1>  _myDependency1;
    private Mock<IMyDependency2>  _myDependency2;
    private MyClassToTest _myClassToTest;

    [SetUp]
    public void SetUp()
    {
        _myDependency1 = new Mock<IMyDependency1>();
        _myDependency2 = new Mock<IMyDependency2>();
        _myClassToTest = new MyClassToTest(_myDependency1.Object, _myDependency2.Object);
    }

    [Test]
    public void Test1
    {
        _myDependency1.Setup(x=> x.GetStuff).Returns(new List<Stuff>());

        // Test code which operates on _myClassToTest …
    }

    [Test]
    public void Test2
    {
        _myDependency2.Setup(x=> x.GetOtherStuff).Returns(new List<OtherStuff>());

        // Test code which operates on _myClassToTest …
    }   
}

There are a number of benefits to this approach. You only have to call new … on each of your object types once and only once. Your test runner will run your [SetUp] / [TestInitialize] method prior to each test method being executed, which wipes out any .Setup(x=>…)s you had for other tests, preserving the independent/isolated nature of your tests (the “I” in the A TRIP mnemonic). Lines of code are reduced, encapsulation is preserved, and perhaps most I importantly (for me), forgetting to assign the mock’s .Object back to the code under test is no longer an issue, once you have your setup/initialize method created properly.

This becomes ever more useful as the number of tests you write and the number of constructor-injected dependencies (possibly) increases.

Thursday, 11 October 2012

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s