The Testable Pattern

The Testable pattern, which I believe was coined by Brad Wilson (@bradwilson) co creator of XUnit, provides a nice structure for testing classes that use DI. Brad writes about it here. Essentially it involves creating a sort of wrapper class that derives from the actual class you are testing and exposes mocked, stubbed or faked implementations of its injectable services. The unit test class then works directly with this “Testable” class.

Lets look at a simple example. Here is a class that I want to test:
private readonly IFileWrapper fileWrapper;

public LessHandler(IFileWrapper fileWrapper)
{
    this.fileWrapper = fileWrapper;
}


Without using auto mocking, my Testable class might look like this:
class TestableLessHandler : LessHandler
{
    public Mock<IFileWrapper> MoqFileWrapper { get; set; }

    public TestableLessHandler(Mock<IFileWrapper> moqFileWrapper)
        : base(moqFileWrapper.Object)
    {
        MoqFileWrapper = moqFileWrapper;
    }

    public static TestableLessHandler Create()
    {
        return new TestableLessHandler(new Mock<IFileWrapper>());
    }
}


I create a Moq property for each dependency (I only have one here.) I also have a factory method that creates the testable and passes in mocks of each dependency to the testable constructor. When you have alot of dependencies, this can add up to alot of boiler plate code. Ugh.

Enter Auto Mocking

What auto mocking does is it looks at the dependencies that your class under test use and automatically creates Mocked implementations of the dependencies.

So with auto mocking my testable class now looks like this:
class TestableLessHandler : Testable<LessHandler>
{
    public TestableLessHandler()
    {
        //place for default mock setups
    }
}


Testable<T> is the class exposed by AutoWrockTestable that wires up the auto mocking and exposes it via MOQ.

Here is how an actual test method using AutoWrockTestable might look:
//Create the testable
var testable = new TestableLessHandler();
...
//Access my depencency via Mock method
testable.Mock<IFileWrapper>().Setup(x => x.GetFileString(It.IsAny<string>()))
    .Returns("@brand_color: #4D926F;#header {color: @brand_color;}");
...

//call method I want to test via the ClassUnderTest property
testable.ClassUnderTest.ProcessRequest(context.Object);


The Mock<T> method returns the MOQ class of dependency T. The ClassUnderTest property returns the actual instance of the class that my Testable is wrapping. When I act on this instance, all of its dependencies are mocked with the setups I previously specified.

References

AutoWrockTestable is based on a class I "copy/paste" into all of my test assemblies and I blogged about it here. With AutoWrockTest now a true Assembly, I hope to avoid multiple copy/paste inheritance.

I have been using this class for a couple years and did not realize until now that the original author of the class is Richard Cirerol who first wrote about it here.

Last edited May 15, 2012 at 4:06 PM by mwrock, version 1

Comments

No comments yet.