Friday, August 1, 2008

Mocks and stubs

I am getting to a point where I am designing more and more complex applications. Since I am doing this alone I sometimes find it over whelming when I realize everything I am going to need to do as I progress though an application. Combine this with performing TDD at the same time and you begin to realize just how much work you have ahead of yourself.

Some of the things that I have begun to use in order to make things easier are mocks and stubs. I first heard about mocks and stubs while researching TDD and am beginning to use them for more than just testing. There are some subtle differences between mocks and stubs but they are similar.

Stubs are methods or functions that are only meant as place holders. I have yet to see a stub actually do anything. An example of a stub would be:

public static void SomeMethod(string MyString)
{

}

It doesn't do anything but it will allow code to compile that will need to use this method. Stubs are one of the first steps towards getting your unit tests to pass, if you are following a test driven approach.

Mocks can be anywhere from a little more complex to a lot more complex than a stub. Mocks allow you to create methods/functions that return expected data. They are usually the next logical step in TDD after a stub. Building on the above stub a mock could be:

public static string SomeMethod(string MyString)
{
return "This is my new modified string";
}

This will get a test to pass and it will allow you to test other portions of your code that depend on this method without fully implementing it before you are ready.

Now where mocks really shine is when you start using interfaces. The way I use this is as follows.

public interface IStringManipulator
{
public static string SomeMethod(string MyString)
public static bool IsNull(string MyString)
}

Now that the interface is designed you can start with your mock.

public class mockStringManipulator : IStringManipulator
{
public static string SomeMethod(string MyString)
{
return "This is my new modified string";
}
public static bool IsNull(string MyString)
{
return true;
}
}

You have your mock, now you can use the mock as a placeholder.

public class WebConnector
{
public void Connection(string Username)
{
String NewUsername;
if(!mockStringManipulator.IsNull(Username))
{
NewUsername = mockStringManipulator.SomeMethod(Username)
return NewUsername;
}
else
{
throw NullReferenceException;
}

}
}

You will of course be writing unit tests on the WebConnector class and when you get around to fully implementing the StringManipulator class you will be using the IStringManipulator interface. This ensures that all the only difference between your mock class and your production class is in the implementation. The signatures and everything else matches exactly and since you will be performing TDD on the production class you will have a high degree of confidence that it will work as expected before you change from the mock to the fully developed class.

2 comments:

Nachiappan Ren said...

Nice explanation! very clear and makes someone understand very clearly.

Anonymous said...

You understanding of mocks and stubs is incorrect.

A stub is a method that has been prepared to return static data. The stub is usually part of the class that you are actually trying to test. Your description of "stub" is correct in the sense that an empty method is often called a stub in general OO terms, but for unit testing, that's not what it means.

A mock is an object that is used by the class that you are trying to test and the mock will contain methods that don't have any state, only behavior (thus a method that returns a value isn't, in and of itself, a mock.