TheHumbleProgrammer

Just another WordPress.com weblog

Archive for August, 2008

Mock Object Frameworks Part 2

Posted by thehumbleprogrammer on August 17, 2008

In the first instalment of this series I introduced the idea behind mocking showing a quick example of hand rolling your own stubs in order to test your classes in isolation. In this article I will be going through the types of test doubles you get from Rhino Mocks and why I chose it in the first place.  Rhino Mocks Documentation is a good starting point, after that there are plenty of people blogging on getting started with Rhino Mocks. You can also download and print a cheat sheet,  which is also very useful. For these reasons I won’t be delving too deeply into the usage of Rhino Mocks, I want to focus more on why you would choose it, what the different types of mock objects are and when to use them.

Why Choose Rhino Mocks?

In the previous instalment I outlined several mocking frameworks and some of their main features, at the time of my choosing a framework to use Moq wasn’t around, had it been I may have chosen that one, I will certainly be looking into some of the claims they make. So with this in mind I ended up going for Rhino Mocks. I discounted NMock2 and EasyMock because they use strings for setting expectations e.g.

Expect.Call("mockObject.SomeMethodOrProperty")

The problem with this approach is that if you change the name of any of the methods or properties being mocked the change will not be propagated to your tests. Refactoring is something I do all the time, as my understanding of the system improves I will refactor the code to express this new understanding. Visual Studio is improving in this area by giving us some basic refactoring support. The idea that I would have to do a search and replace in my test suite was a non starter in my mind.

In the end it was between Rhino Mocks and TypeMock. I discounted TypeMock because it’s too powerful. This may seem like a strange reason but I would urge all novice mockers to avoid TypeMock like the plague (links to typemock omitted deliberately :-o ). The fact that you can mock anything is the problem, I believe in unit testing as a way of minimising bugs in your system, leading me to want to build testable systems. A deeply embedded dependency, such as a static call to a method that hits the database means that it cannot be tested in isolation without the use of TypeMock. So what, I hear you say, the system can still be tested and the method can be tested in isolation, so there is no problem right? Well if you have considered the effects of this embedded dependency and have decided that they are within acceptable boundaries then by all means carry on. You have done some thinking and recognised the tradeoffs and made an informed decision, that is what software development is all about, too avoid being a Cargo Cult Programmer. If on the other hand you embed that dependency because that is all you know, and with the help of TypeMock you can keep the coverage high as your system evolves into a nice big ball of mud, then you have problems, more specifically the maintainer of your code will have problems, lets hope they are not a psychopathic axe murder, or worse yourself.

Different types of test doubles

Out of the box Rhino gives us four different types of test doubles, each one is specific to different scenarios. The four are

Stub

Gives us a ready to use sub classed implementation of the collaborating class we want to substitute in our tests. A stub offers us a mechanism to inject test data into our unit under test without having the method call to the stub verified.  If you are doing a classic state based test where the unit under test collaborates with some object that you want to substitute then use a stub. Here is an example method that I want to test

public string FormatContactDetails(Message message)
{
    string contactDetails = message.GetContactDetails();
    //formating code here...
    return contactDetails;
}

This method could be from some messaging system where I want to get contact details from the given message, I don’t have any control over how the message is created I just know that it is part of the messaging framework. I want to do a state based test that the returned string is in the correct format, but I don’t want to go to the hassle of creating a Message instance because it may have too many dependencies on the framework. The test would look something like this

[Test]
public void Should_Return_ContactDetails_In_Correct_Format()
{
    MockRepository mockRepository = new MockRepository();
    //you could also use MockRepository.GenerateStub<Message>();
    Message messageStub = mockRepository.Stub<Message>();

    SetupResult.For(messageStub.GetContactDetails()).Return("some contact details");
    mockRepository.ReplayAll();

    Customer customer = new Customer();
    string formattedDetails = customer.FormatContactDetails(messageStub);

    //Make assertions on the state of formattedDetails
}

I create a stubbed message by calling Stub<Message>() on the repository of mocked objects. I then setup the test data to be used in the unit under test by calling SetupResult.For, this line tells the framework to return the string “some contact details” when GetContactDetails() is called during the execution of customer.FormatContactDetails, which is the unit under test. Calling mockRepository.ReplayAll() will move all of the mocked/stubbed objects in the repository from the record state into the replay state. Finally I can make all the assertions I need on the returned string to ensure that the formatted details are correct.

Dynamic Mock

Dynamic mocks give you loose replay semantics, this means that all expectations that are set must be met or your test will fail, but unexpected method calls will not cause the test to fail. You can use dynamic mocks as stubs but as the stub documentation suggests this is a lot of work for very little gain. Dynamic mocks come in handy on the rare occasion when you may have one method call to a collaborator that you care about whilst all other interactions with the same collaborator are not so essential.

UPDATE: 11.10.2008 – With the release of Rhino Mocks 3.5, Ayende confirmed what I had already concluded myself;

CreateMock is deprecated, replaced by StrictMock. The use of Strict Mock is discouraged

We should be using dynamic mocks instead of strict mocks, making our tests less brittle and easier to refactor.

Partial Mock

As the documentation suggests (the heading is a link :-) ) partial mocks are useful for when you want to test abstract methods in isolation. Another use for partial mocks is when breaking dependencies in a legacy code base. By legacy code I mean untested tightly coupled spaghetti code that most of us see produced by the A grade whiz bang team assembled to get version 1 of the latest Greenfield project going, and this time they are going to get it right :-o . Anyway an example of said code could be.

public string FormatContactDetails()
{
    string formattedDetails = string.Empty;
    ContactDetails details = ServiceController.Instance.GetContactDetails(this.CustomerID);
    //code to turn the contactDetails into a formatted string

    return formattedDetails;
}

In order to test the FormatContactDetails method in isolation I want to break the dependency on that static call to the database using the ServiceController. The point of my test at this stage is to ensure that the returned string is in the correct format, I don’t care about the database call, that should have been tested in an integration test suite. The first thing to do is to move it out into a public virtual method

public string FormatContactDetails()
{
    string formattedDetails = string.Empty;
    ContactDetails details = GetContactDetails();
    //code to turn the contactDetails into a formatted string

    return formattedDetails;
}

public virtual ContactDetails GetContactDetails()
{
    return ServiceController.Instance.GetContactDetails(this.CustomerID);
}

then I can sub class and override it in my tests. I can use a partial mock for this,

[Test]
public void Should_Get_formatted_ContactDetails_Without_Hitting_The_DB()
{
Customer customer = this.mockRepository.PartialMock<Customer>();

Expect.Call(customer.GetContactDetails()).Return("just testing");
this.mockRepository.ReplayAll();

string formattedAddress = customer.FormatContactDetails();

Assert.AreEqual("just testing", formattedAddress);
}

I have created a partial mock of the Customer class where the FormatContactDetails behaviour resides, I am then setting up an expected call on the virtual method GetContactDetails telling the framework that when the method call is executed return “just testing”. After moving the partial mock to the replay state from the record state I then call the unit under test. Finally I can make some assertions on the returned string to see that it is in the correct format, although I haven’t done in this test you can also verify that the expected call has been met.

Mock

Mock implementations of collaborating classes enable us to verify that methods were called correctly during the execution of the unit under test. Mocks are used when the interaction between a unit under test and it’s collaborators is the essence of the test. Mocking a collaborator gives us a strict record/replay model, this means that every expectation that is set must be met, also If a method is called on a mocked object without setting an expectation the test will fail.  When you mock an object using a call to CreateMock like so

Customer customer = this.mockRepository.CreateMock<Customer>();

you are saying that this is an interaction based test, the interaction between the unit under test and the mocked object is all important. It should be verified that all expectations have been met and that no calls have been made on the mocked object unexpectedly.

Conclusion

In this article I explained the reasons behind my choosing Rhino mocks for dynamically mocking dependent objects in my unit tests. I also went through the four types of test doubles that Rhino mocks gives you out of the box. These four types should give you all the functionality you need to unit test your classes in isolation without having too maintain a suite of hand rolled fakes, as you refactor your system. The important thing to realise is that there is more to a dynamic mock object framework than just pure mocking to enable interaction based testing. With this in mind you should have a clear understanding of what is important in each unit test and use the framework accordingly.

In the next instalment I will be outlining some general rules of thumb for incorporating Rhino mocks in your tests, I will also delve into some of the more common gotchas that may have you scratching your head when you first start using the framework.

Posted in Mock Object Frameworks, Test Doubles, Unit testing | 2 Comments »

Mock Object Frameworks

Posted by thehumbleprogrammer on August 1, 2008

In the last 18 months I have been doing a good deal of experimentation with mock object frameworks. Trying to understand mocking frameworks, when to use them and when not to has been a painful experience, but one that I feel everyone should go through in order to come out the other side, with a deep seated knowledge of building testable systems. This is the first in a series of posts explaining my understanding of mock objects and the frameworks out there.

Introduction

Substituting real implementations of an interface with a mocked implementation is a technique used in unit testing that gives you the following benefits:

  1. Keeps your unit tests fast running.
  2. Enables you to test your classes in isolation.
  3. Usually leads to a well designed loosely coupled system.

Fast running unit tests are essential to keeping the developers interested in running and maintaining test coverage during the development of a system. When I first tried unit testing a production system I soon became unstuck with tests that relied upon external resources that I had no control over such as database calls, SMTP, the file system etc. When this happens the tests become unrepeatable and slow, from then on other developers didn’t run the tests often, meaning that the test suite became an un trusted, maintenance nightmare with very little benefit. In order to keep your tests running fast you must mock out these external dependencies, tests that incorporate the database calls etc can, and should be included in an integration test suite that is separate from your unit tests. Points two and three are resulting side effects that are beneficial in their own right when you have a fast running, repeatable suite of unit tests.

The mistakes I made in the above mentioned project lead me down the path of Mock object frameworks. So far in this article I have used the term Mock to mean any type of implementation used as a substitute in your tests. There are several different types of Test Doubles that can be used, each of them enable you to take different approaches in your unit tests. Over this series of articles I will be delving more deeply into the different approaches to writing unit tests but for now I will use Martin Fowler’s definitions from his article Mocks Aren’t Stubs without going into too much detail.

Mock objects

pre-programmed with expectations which form a specification of the calls they are expected to receive

Stubs

provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it ’sent’, or maybe only how many messages it ’sent’.

Fakes

objects actually have working implementations, but usually take some shortcut which makes them not suitable for production

A common example throughout these articles will be to develop a Presenter that collaborates with a view and a model (MVP), I will be substituting implementations of these dependent objects with mocks/stubs/fakes. This allows me to construct the presenter without worrying about the implementation details of the view and the model. In my opinion this is a very important benefit of mocking because it allows me to concentrate on doing one thing and one thing only.

The Manual Approach

The manual approach to achieving this isolation is to implement your own stubs that return test data when the methods are called. The following is a CustomerOrdersPresenter that interacts with an ICustomerOrdersView and an IDataProvider (the model). In the constructor of the presenter I want to attach to the views load event so my test for this is…

[Test]
public void Should_Attach_To_Load_Event()
{
ICustomerOrdersView customerOrdersViewStub = new CustomerOrdersViewStub();
CustomerOrdersPresenter presenter =
new CustomerOrdersPresenter(customerOrdersViewStub, _customersDataProvider);
Assert.IsNotNull(presenter, "Presenter should not be null");
Assert.IsTrue(((CustomerOrdersViewStub)customerOrdersViewStub).InvocationListCount > 0,
"the invocation list of the Load event should be greater than 0");
}

As you can see I have created a new instance of the CustomerOrdersViewStub, which is my own hand rolled implementation of the ICustomerOrdersView. As well as implementing the interface functionality I have added some properties and methods to allow me to write useful tests. In this case I have added a InvocationListCount property that allows me to get at the Load events invocation list.

internal class CustomerOrdersViewStub : ICustomerOrdersView
{
//ICustomersView implementation
....
//added property for testing
public int InvocationListCount
{
get { return this.Load.GetInvocationList().Length; }
}
}

Finally the implementation of the CustomerOrdersPresenter’s constructor is

public class CustomerOrdersPresenter
{
private readonly ICustomerOrdersView _view;
private readonly IDataProvider _provider;
public CustomerOrdersPresenter(ICustomerOrdersView view) :this(view, new CustomerDataProvider())
{ }
public CustomerOrdersPresenter(ICustomerOrdersView view, IDataProvider provider)
{
_view = view;
_provider = provider;
_view.Load += new EventHandler(View_Load);
}
}

The benefits of the manual method are
  • No learning curve (we all know how to write code).
  • Complete control over the stub
The downside of the manual method is
  • Can quickly become a nightmare to maintain two sets of implementations.
  • A lot of code to write just to get useful fine grained tests.

Although the downside to the manual method is quite significant I would advise anyone starting out unit testing to use it until they are completely happy with writing good unit tests. With hindsight I probably went over to mock object frameworks too early in my unit testing career, this lead to a lot of frustration with trying to learn two things at once.

Mocking Frameworks

In order to avoid writing your own stubs for testing purposes you can incorporate a mock object framework to do the work for you. As I said earlier I found the learning curve is pretty steep but as with all things it gets easier over time. Of course some of you geniuses out there will probably get it straight away, or you may have a colleague who has used the frameworks before. All I can say is give yourself a pat on the back and sit back with your hands cradling the back of your head allowing a nice smug grin to appear on your face.For the rest of us the different frameworks are:

  • TypeMock
    • Free and professional versions.
    • Allows you to mock anything, including static methods.
    • Has a fluent interface.
    • pro version is quite expensive.
    • You don’t have to inject mocked objects
  • NMock2
    • Free open source project.
    • Allows you to mock classes and interfaces.
    • Uses strings to set the expectations on method calls.
    • Uses a fluent interface.
    • You have to inject dependent mock implementations in order to set expectations on them.
  • RhinoMocks
    • Free open source project.
    • Allows you to mock classes, interfaces and delegates.
    • Developed with refactoring in mind, by using the strongly typed mock object’s instead of strings to set your expectations.
    • Uses a fluent interface.
    • You have to use Dependency Injection in order to substitute the real implementation with a mock/stub.
  • MoQ
    • Free open source project.
    • Allows you to mock classes, interfaces and delegates.
    • Uses strongly typed mocks when setting expectations.
    • Uses a fluent interface.
    • No record/replay/verify syntax

With the exception of MoQ all of the frameworks use a record/replay/verify model. This means that you record a set of expected behaviour then you verify that all of the expectations were met after the replay. The record/replay model is only important when you are using pure mock objects (not stubs) in an interaction based test. State based testing is the more familiar to most developers, where you set up some test data and call the unit under test and assert that the state of the object meets some post condition. When doing interaction based testing the assertions being made are based on the interaction between the unit under test and its’ collaborators. This will hopefully become clearer as I produce some demo code in later instalments of this series.

In the next article I will be delving into the reasons behind why I chose RhinoMocks. I will also be showing more code examples of writing unit tests using RhinoMocks.

Posted in Unit testing | 6 Comments »