GuestPost: Introduction to Mocking
Note: Cross posted from IUpdateable from Eric Nelson.
I have previously posted on the area of Test Doubles and Mocking under the guise of Project NEric. I also have blogged on specific tools such as Pex and TypeMock – but I wouldn’t claim to be an expert on the area. Far from it.
Luckily I know a man who is. Meet Gil Zilberfeld who works at TypeMock and kindly agreed to do a couple of guest posts on Mocking. This is the first of those two. I should get the second online next week when I return from holiday. Thanks again Gill.
Introduction to Mocking by Gill Zilberfield
It was about 4 years ago, when I decided to try TDD (Test Driven Development). I was a project manager at the time, and I had a rule – never test anything on your team, before you try it (on) yourself. I was writing a communication server at the time, and thought – hey, why not?
Starting was easy. I added a couple of interfaces, checked that the object is created correctly. And then I got to the heart of the matter – the component used MSMQ as a messaging infrastructure. Sending a message to the queue was easy. Checking that it got there – well that’s another story.
My success for criteria for my test for sending a message was to check that the message arrived. And it arrived. Sometimes before the test ended (success) and sometimes after (failure). You see, MSMQ has a mind of its own (also known as asynchronous behavior). I couldn’t control its behavior, so I had to replace it with another object I could control. This was my first mock object.
Mocking is generally an overloaded term. But at its base - it’s about changing behavior. Which behavior? Dependency behavior.
Let’s look at my class:
public class Server
{
public void SendMessage(IMessageQueue queue, object message)
{
queue.Send(message);
}
}
I need to send the message to the queue. But, like I said, queue (which is the dependency of Server) sometimes behaves funny. And we don’t like funny, we like dependable. Let’s change the signature a bit:
public class Server
{
public void SendMessage(IMessageQueue queue, object message)
{
queue.Send(message);
}
}
This time, I’m not sending a MessageQueue object. Instead, I’m sending the IMessageQueue interface, which looks like this:
public interface IMessageQueue
{
void Send(object message);
}
Now that I can inject any object implementing the IMessageQueue interface. For example, my real Message Queue object looks like this:
public class RealMessageQueue : IMessageQueue
{
var queue = MessageQueue.Create("AnyQueue");
public void Send(object message)
{
queue.Send(message);
}
}
But another, a fake message queue object can look like this:
public class FakeMessageQueue : IMessageQueue
{
public bool messageWasSent = false;
public void Send(object message)
{
messageWasSent = true;
}
}
As you can see, with the FakeMessageQueue, I can actually test that the message was sent:
[TestMethod]
public void Send_StringMessage_MessageWasSent()
{
var fakeMessageQueue = new FakeMessageQueue();
var server = new Server();
server.SendMessage(fakeMessageQueue, "message");
Assert.IsTrue(fakeMessageQueue.messageWasSent);
}
And that’s the whole idea behind mocking - the ability to change behavior. This is a very tiring way to do that. Today, there are tools to do the same thing, with much less hassle: Isolation frameworks. In my next post, I’m going to talk about one of them: Typemock Isolator.
Gil Zilberfeld