Mocking Test Driven Development

I should get an award for eye-catching titles. This article is actually about using Mocks when coding your tests for Test Driven Development. For this stuff to work, make sure you install nUnit and download NMock2.

One of the main principles of TDD is to create your tests in such a way that they test a specific part of your application (a “unit”), instead of several parts that are co-dependent (a “system”). The easiest way to do that is by using a Mock – which is a “fake” representation of an interface. Consider the following scenario:

You have a data model that calls a web service to verify an employee’s username and password. We’re going to focus on developing the data model, so how or where it gets its data from is entirely unrelated to the tests. The first requirement of this kind of testing is that all your individual units are separated from each other using Interfaces. So, we might have an interface as follows:

1
2
3
4
public interface IEmployeeProvider
{
    bool LoginEmployee(string username, string password);
}

Good start. Now, being the good TDDers we are, we go and write our first test – “If the username is null or empty, throw an ArgumentNullException”. This is also an example of “Fail First” programming, which is a good mindset to have in TDD – identify all the points of failure before you focus on success. Anywho, let’s say our DataModel class looks like this:

1
2
3
4
5
6
7
8
9
public class EmployeeDataModel
{
    private IEmployeeProvider _employeeProvider;

    public EmployeeDataModel(IEmployeeProvider employeeProvider)
    {
        this._employeeProvider = employeeProvider;
    }
}

Having our class setup like this allows us to pass in the data provider we want to use, which is also a good “separation of concern” – if we ever need to change our data access method in the future, it’s just a matter of creating new providers and slapping them in the model constructors. So, knowing this, let’s write our first unit test. I’m going to use nUnit attributes, but the MSTest ones are fairly similar. Also of note is the fact I’m using NMock2 instead of the mocking classes that come with nUnit, simply because nUnit hasn’t updated their mocks since .NET 2.0 and they’re planning on dropping them alltogether.

1
2
3
4
5
6
7
8
9
10
[Test(Description="If the username is null or empty, throw an ArgumentNull exception")]
[ExpectedException(ExpectedException=typeof(ArgumentNullException))]
public void NullUsernameOrPassword()
{
    Mockery mocks = new Mockery();
    //this is just creating a mock object based on an interface type and then casting it to the interface object
    IEmployeeProvider provider = mocks.NewMock(typeof(IEmployeeProvider)) as IEmployeeProvider;
    EmployeeModel model = new EmployeeModel(provider);
    model.Login("", "password");
}

So there’s our test. A few things to point out – the syntax for creating Mock objects, which is specific to NMock2 but fairly standard for other mocking schemes. Once we’ve made our “mock” object, which as far as .NET is concerned is a IEmployeeProvider object, we can construct our EmployeeModel object. Also, you’ll notice that I’ve called model.Login(string, string), which doesn’t even exist yet. That’s the point of TDD – we identify code that we NEED, instead of just writing code on the fly. We obviously need a login method, so we’ll add:

1
2
3
4
public bool Login(string username, string password)
{

}

… and JUST that. Why not go in and write all our fancy exception throwing stuff? Well, why don’t we just write up the whole class then I know it’s definitely different from what we’re used to, but in TDD your test should fail before it passes, so you can definitively say the code you added made the test pass. Yeah, I know, lame, but stick with me. Now your code should compile, and you should be able to run your test in NUnit GUI (start a new project, go to Project –> Add Assemblies, find your DLL and add it). And the test should fail, obviously, but that’s the point Let’s go finish that method.

1
2
3
4
5
public bool Login(string username, string password)
{
    if(string.isNullOrEmpty(username))
        throw new ArgumentNullException("Username must have a value");
}

Now, if you rebuild and retest, everything should work and nUnit should be all green. Congrats, you just did your first unit test! For homework, do the same with Password. On a side note, some of you might be wondering “Why didn’t we do a test for username AND password?” Because they’re separate properties, and you’d have potentially separate outcomes based on the input of either of them, you should test your properties (and explicit combinations thereof) in separate tests. If you expect a different outcome if both username AND password are blank, then you’d have 3 tests to write.

Man, I’ve added quite a bit and haven’t even got to mocks yet. Well, I’ll do that tomorrow. Until next article

Comments