The magic of AutoMocks

I'm sure most of you have come across a test like this when you've been looking at or writing unit tests.

    [Test]
    public void Test()
    {
        var dependantClass = MockRepository.GenerateMock<IDependantClass>();
        var anotherDependantClass = MockRepository.GenerateMock<IAnotherDependantClass>();
        var yetAnotherDependantClass = MockRepository.GenerateMock<IYetAnotherDependantClass>();

        var classUnderTest = new ClassUnderTest(dependantClass, anotherDependantClass, yetAnotherDependantClass);

        //Some action

        //Some assertion
    }

Wouldn't it be nicer if you could just ask something to get you the class that you want to test and mock out any interfaces that are required by the constructor? Well that's precisely the idea behind a number of frameworks out there at the moment such as AutoMock.

The framework I'm going to use in the next couple of examples is an extension for Ninject called MockingKernel and is available on Nuget. The examples are using RhinoMocks but there are also packages available for Moq and NSubstitute. It's also available on GitHub so you can add support for anything else that you want to.

Using MockingKernel you can now write your code like this

    [Test]
    public void AutoMockedTest()
    {
        var kernel = new RhinoMocksMockingKernel();

        var classUnderTest = kernel.Get<ClassUnderTest>();

        //Some action

        //Some assertion
    }

Under the hood RhinoMocks has been used to mock out all the dependencies of ClassUnderTest.

If we wanted to set an expectation on our IDependantClass and then verify it was called we would do it as follows.

    [Test]
    public void AutoMockedTest()
    {
        var kernel = new RhinoMocksMockingKernel();
        kernel.Get<IDependantClass>().Expect(dc => dc.SomeMethod(1)).Return(true);

        var classUnderTest = kernel.Get<ClassUnderTest>();

        //Some action

        kernel.Get<IDependantClass>().VerifyAllExpectations();
    }

A lot of test classes I've seen have a very similar setup section. The dependencies for the class under test (or target) are created through a mocking framework and passed into the class under test. So using our example above you would probably see this.

public class AutoMockTests
{
    private IDependantClass _dependantClass;
    private IAnotherDependantClass _anotherDependantClass;
    private IYetAnotherDependantClass _yetAnotherDependantClass;

    private ClassUnderTest _classUnderTest;

    [SetUp]
    public void SetUp()
    {
        _dependantClass = MockRepository.GenerateMock<IDependantClass>();
        _anotherDependantClass = MockRepository.GenerateMock<IAnotherDependantClass>();
        _yetAnotherDependantClass = MockRepository.GenerateMock<IYetAnotherDependantClass>();

        _classUnderTest = new ClassUnderTest(_dependantClass, _anotherDependantClass, _yetAnotherDependantClass);
    }

    [Test]
    public void AutoMockedTest()
    {
        _dependantClass.Expect(dc => dc.SomeMethod(1)).Return(true);

        //Some action

        _dependantClass.VerifyAllExpectations();
    }
} 

A side effect of using our AutoMock framework means that you can now move this up into a base class as the test class no longer needs to know what the dependencies of the class under test are. So for example you might have the following base class

public class TestBase<T>
{
    private IKernel _kernel;
    protected T Target;

    [SetUp]
    public void TestBaseSetUp()
    {
        _kernel = new RhinoMocksMockingKernel();
        Target = _kernel.Get<T>();
    }

    protected TDependency GetDependencyOf<TDependency>()
    {
        return _kernel.Get<TDependency>();
    }
}

This means that our test setup has been removed completely. You just have to set up any expectations in the test itself. So your test class now becomes this.

public class AutoMockTests : TestBase<ClassUnderTest> 
{
    [Test]
    public void AutoMockedTest()
    {
        GetDependancyOf<IDependantClass>.Expect(dc => dc.SomeMethod(1)).Return(true);

        //Some action

        GetDependancyOf<IDependantClass>.VerifyAllExpectations();
    }
}

This helps to remove a lot of the clutter around your tests and makes it much easier to see what your tests are actually doing. Which is always a good thing!