TheHumbleProgrammer

Just another WordPress.com weblog

Archive for the ‘Test Doubles’ Category

Mock Object Frameworks Part 3

Posted by thehumbleprogrammer on September 23, 2008

In part 1 of this series I introduced the idea of substituting collaborating objects with test doubles in order to unit test your classes in isolation. In part 2 I then went on to introduce reasons to choose Rhino Mocks and the four types of test doubles rhino mocks gives you in order to carry out state or interaction based unit testing. In this article I am hoping to introduce testing events as well as some of the more common gotchas that catch out beginner users of Rhino mocks.

Understanding Error Messages

For beginner users of the Rhino mocks framework the biggest issue can be in trying to understand the error messages that are returned when an exception is thrown.

[Test]
public void Should_Call_GetById_When_Handling_The_View_Load_Event()
{
   this.Setup();
   IService<Customer> serviceMock = repository.StrictMock<IService<Customer>>();
   Expect.Call(serviceMock.GetById(4)).Return(this.customer);
   this.repository.ReplayAll();

   CustomerPresenter presenter = new CustomerPresenter(serviceMock, this.customerViewDMock);
   presenter.HandlePageLoad();
   this.repository.VerifyAll();
}

In the test method above I am creating a strict mock on line 3, I then set an expectation that the GetById() will be called and when it is, return the customer instance created earlier in the Setup(). The call to ReplayAll() on the repository lets the framework know that the record phase is complete and we are ready to playback any expectations during the execution of the unit under test. I then create the presenter instance and call the unit under test, which in this case is HandlePageLoad(). Finally I call VerifyAll() on the repository to assert that the expectations set earlier have been met.

When run the test fails with the following message;

Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById(4); Expected #1, Actual #0.

As you can see an ExpectationViolationException has been thrown. The error message that we are interested in begins after the colon, it’s telling us that a call to IService.GetById(4) was expected once but actually called zero times. In this case I am doing an Interaction based test to ensure that GetById() on the service is called, because I have not implemented the HandlePageLoad() method on the presenter the expectation set in the record phase has not been met during the replay, resulting in the above exception. To fix this I add the following to the HandlePageLoad() method.

public void HandlePageLoad()
{
    Customer toDisplay = this.Service.GetById(4);
}

As you can see I have implemented just enough to get the test to pass, I have hard coded in the customer id in the call to GetById(4). In reality the customer id will be retrieved from the View.CustomerId property. I change the implementation to make the call to the view like so;

Customer toDisplay = this.Service.GetById(this.View.CustomerId);

Now I get the following error message.

Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById<System.Int32>(0); Expected #0, Actual #1.
IService`1.GetById<System.Int32>(4); Expected #1, Actual #0.

Because I am using a strict mock the framework finds two expectation violations.

  • GetById<System.Int32>(0); Expected #0, Actual #1 – is caused by the call to GetById() in the HandlePageLoad() implementation, because I am now getting the customer id from the view and I have not setup any value for it to return (the view is a strict mock controlled by the framework) customerid will always return the default value, in this case 0. The expectation violation is caused by the GetById(0) being called in the implementation and not having an Expect.Call(… etc set for it in the record phase of the unit test.
  • GetById<System.Int32>(4); Expected #1, Actual #0 – is caused by the Expectation not being met for a call to the GetById(4) method with a parameter value of 4. We explicitly set this expectation in the unit test before the call to ReplayAll().

In short this whole issue is being caused by the parameter value being used in setting the expectation, I am using the hard coded value 4 in the expected call to GetById() but in the implementation GetById() is being called with the default customer id, which in this case is 0. We can remedy this situation by using IgnoreArguments like this;

Expect.Call(serviceDMock.GetById(4)).IgnoreArguments().Return(this.customer);

Adding a call to IgnoreArguments tells the framework to ignore any values passed into the call to GetById during the execution of the method under test. Now my test is more robust because it will fail when the GetById is not called but if the customer id property changes on the view it will have no effect on the test.

By carefully looking at the error message above we can see that the first part says that a call to IService.GetById(0) was not expected but called anyway and a call to IService.GetById(4) was expected but not met. With value types the clue is in the error message we can see the 0 and the 4 are the parameters making it that bit easier to figure out what is going on. When using reference types we get an even more cryptic error message, by changing the GetById so that it takes a Customer object setting the expectation looks like this;

Expect.Call(serviceMock.GetById(new Customer())).Return(this.customer);

and the new implementation looks like this;

//this is a simple implementation for demo purposes only
Customer toDisplay = this.Service.GetById(new Customer());

and when run the error message looks like this;

Rhino.Mocks.Exceptions.ExpectationViolationException: IService`1.GetById(Rhino.CommonGotchas.Customer); Expected #0, Actual #1.
IService`1.GetById(Rhino.CommonGotchas.Customer); Expected #1, Actual #0.

The parameter being passed in to the GetById(Customer) is the problem. When I set the expectation in the record phase of the unit test I passed in a new Customer and when I implemented the HandlePageLoad() method I also passed  in a new Customer in the call to GetById. The framework is using reference equals to check that the parameter being passed in the expectation is the same as the parameter being used in the actual implementation. In this case they are not, so we get the message GetById(Customer) wasn’t expected but actually called, GetById(Customer) was expected but never called. Again IgnoreArguments sorts this out but the error message is very confusing.

More Flexibility Using Dynamic Mocks

I get the two tier error message above because I am using strict mocks and as we all know from part 2 strict mocks will fail a test when either all expected calls have not been met or if unexpected calls are made on the mocked object during the execution of the unit under test. If however we use a dynamic mock in the above example we will only get the one error message. The framework will ignore the fact that a call has been made with the incorrect parameter and will fail on the fact that the expectation has not been met. The expectation has not been met because we have made an explicit expectation that a call to the GetById(param) will be called, we have not let the framework know that the parameters are not important so it will fail the verification. Once I tell the framework to ignore parameters the test will pass.

As a side note this is another reason why I am moving towards using dynamic mocks as apposed to strict mocks. They allow you to write more flexible interaction based tests that will fail for the right reason. So in the example above If someone refactors the implementation in such a way that the call to GetById(int) does not happen then the test will fail, the developer will see a failing test named Should_Call_GetById_When_Handling_The_View_Load_Event() and they can then decide whether in light of the refactoring this is a valid test or not.

Don’t Forget ReplayAll()

Not calling replay all on a series of expectations or when setting up results on stubs can cause many side effects, ranging from null pointer exceptions in the best case to an incorrectly passing test in the worst case. The most common time to be caught out by this scenario is when you are stubbing out a collaborator and you just want a quick one line way of setting up a result when the stub is called. The example in this section is for saving a customer that has been updated on the view to the database. The (contrived ;-) )  implementation  of the save method is as follows;

public void Save()
{
    Customer customer = this.View.GetCustomer();
    string phoneNumber = customer.Telephone;
    //do some validation on the phone number....
    this.Service.Save(customer);
}

I am getting the updated customer from the view, then getting the telephone number from the returned customer and validating that it meets some criteria finally I am saving it to the database. In my first test for this I want to ensure that only valid phone numbers are being saved to the database, so I stub the view and the service in order to assert state, like so;

[Test]
public void Should_Validate_PhoneNumber_Before_Saving()
{
    this.Setup();
    Service<Customer> serviceStub = repository.Stub<Service<Customer>>();
    ICustomerView viewStub = this.repository.Stub<ICustomerView>(); 

    Customer customerToSave = GetCustomerToSave(); 

    SetupResult.For(viewStub.GetCustomer()).Return(customerToSave);
    serviceStub.Save(new Customer());//Tell the framework a call to save, which is a void method will be made
    LastCall.Callback(new Delegates.Function<bool, Customer>(this.AssertPhoneNumberIsValid)); //Set a callback on the call to save so that I can assert on the phone number 

    CustomerPresenter presenter = new CustomerPresenter(serviceStub, viewStub);
    presenter.Save();
}

I then setup a result on the GetCustomer() method  telling the framework to return the dummy customer when it is called during the execution of the unit under test. On the next line I set a call to a the void method Save(customer) on the service, following it by setting a callback method on the lastcall made by the repository. This callback method will contain all of the assertions on the phone number to ensure that only valid customers are sent to the database. When I run this test I get a null pointer exception in the second line of the Save() method on the presenter. In this line I am trying to retrieve the telephone number from the customer returned from the view, but the view’s GetCustomer() is returning null. I have set a result on the call to GetCustomer() to return a customer instance so I should not be getting a null pointer. The reason behind this is because I have forgotten to call Repository.ReplayAll() to set the repository into the replay phase. Once I put in the missing line the test works as expected, the test now looks like this;

[Test]
public void Should_Validate_PhoneNumber_Before_Saving()
{
    this.Setup();

    Customer customerToSave = GetCustomerToSave();

    ...
    this.repository.ReplayAll();

    CustomerPresenter presenter = new CustomerPresenter(this.serviceStub, viewStub);
    presenter.Save();
}

As with all of these things I have options, first up I could use a using block with a call to Repository.Record() like this;

[Test]
public void Should_Validate_PhoneNumber_Before_Saving()
{
    this.Setup();
    Service<Customer> serviceStub = repository.Stub<Service<Customer>>();
    ICustomerView viewStub = this.repository.Stub<ICustomerView>();

    Customer customerToSave = GetCustomerToSave();

    using (this.repository.Record())
    {
        SetupResult.For(viewStub.GetCustomer()).Return(customerToSave);
        serviceStub.Save(new Customer());//Tell the framework a call to save, which is a void method will be made
        LastCall.Callback(new Delegates.Function<bool, Customer>(this.AssertPhoneNumberIsValid)); //Set a callback on the call to save so that I can assert on the phone number
    }

    CustomerPresenter presenter = new CustomerPresenter(serviceStub, viewStub);
    presenter.Save();
}

When the record block is exited a call to ReplayAll() is made behind the scenes in that way you don’t have to remember to call it explicitly. I feel that by using the block in this test increases the noise to code ratio making the code that little bit harder to understand. Also Record blocks are usually followed by PlayBack blocks that make the whole test easier to understand, as a rule of thumb I only use these blocks if I have 3 or more lines of expectations and Stubbed result setup in my tests. I feel that any less than that the using blocks cause too much noise for very little benefit. That is especially so in a state based test where you are purely stubbing out collaborators.

Setters and Stubs

Once you get passed the Record/Replay/Verify stuff and you have some understanding of the difference between Mocks/Stubs/Fakes/Dummies you will probably grow to enjoy using the framework to make your tests easier to write and maintain. As you get more accustomed to using the framework you will probably do as I did and forget that you don’t have to Setup Results on a stubbed object that has a read/write property, all you need to do is set the property on the stub and it will just work as expected. It seems obvious and it is obvious but you will probably forget about the setter and try to setup result like this;

the view interface

public interface ICustomerView
{
   int CustomerId { get; }
   Customer Customer { get; set; }
   void AttachDataSource(Customer dataSource);
   Customer GetCustomer();
}

As you can the Customer property is read/write the test method that stubs out the view is carrying on with the theme outlined above and looks like this;

[Test]
public void Should_Validate_PhoneNumber_Before_Saving()
{
   this.Setup();

   Customer customerToSave = GetCustomerToSave();

   SetupResult.For(this.viewStub.Customer).Return(customerToSave);
   serviceStub.Save(new Customer());//Tell the framework a call to save, which is a void method will be made
   LastCall.Callback(new Delegates.Function<bool, Customer>(this.AssertPhoneNumberIsValid)); //Set a callback on the call to save so that I can assert on the phone number
   this.repository.ReplayAll();

   CustomerPresenter presenter = new CustomerPresenter(this.serviceStub, viewStub);
   presenter.Save();
}

The third line of the test, in bold, sets up a result on the views’ customer property to return a dummy instance to save. It all looks very familiar, when I run this test I get the following error;

System.InvalidOperationException: Invalid call, the last call has been used or no call

has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).

As you can see from the test above I am calling a virtual method and a call has been made, I also don’t think knowing that the last call has been used really helps me in this scenario. The problem is being caused by me forgetting to set the Customer property directly on the Stubbed view like this;

[Test]
public void Should_Validate_PhoneNumber_Before_Saving()
{
   this.Setup();

   Customer customerToSave = GetCustomerToSave();

   this.viewStub.Customer = customerToSave;
   ...
}

Testing Events

There are two areas to testing events,

  1. Test that subscribers attach to events correctly
  2. Test that when thrown the event is handled

Thankfully rhino mocks gives us some mechanisms to carry out both types of tests. In my first test, again using the theme of a customer presenter instead of using direct calls from the view to the presenter I will be communicating through events. This first test is to ensure that when the presenter is constructed the Load event of the view is attached to. The test looks like this;

[Test]
public void Should_Attach_To_Page_Load_On_View()
{
    this.Setup();

    Expect.Call(() => this.customerViewDMock.Load += null ).IgnoreArguments();
    this.repository.ReplayAll();

    new CustomerPresenter(this.serviceStub, this.customerViewDMock);
    this.repository.VerifyAll();
}

As you can see it’s pretty straight forward, in the second line of the test I am setting up an expectation that something will attach to the Load event of the view. I then instruct the framework to IgnoreArguments on the expectation, in this case the null being attached to the Load event. You can also set constraints on the last call specifying things like Is.NotNull on anything attaching to the event. I then instantiate the presenter, which is the unit under test, and verify that all expectations have been met. In order to pass the test I implement the following constructor;

public CustomerPresenter(IService<Customer> service, ICustomerView view)
{
    this.Service = service;
    this.View = view;
    this.View.Load += ((sender, args) => Console.WriteLine("view loading"));
}

The next thing to test is handling the load event, the first test I want to do is an interaction based test to ensure that the GetById() method is called on the service. My test looks like this;

[Test]
public void Should_Call_GetById_On_Service_When_View_Loads()
{
    this.Setup();
    IService<Customer> serviceMock = repository.StrictMock<IService<Customer>>();

    IEventRaiser loadRaiser =
        Expect.Call(() => this.viewStub.Load += null).IgnoreArguments().GetEventRaiser();

    Expect.Call(serviceMock.GetById(4)).Return(new Customer());
    this.repository.ReplayAll();

    new CustomerPresenter(serviceMock, this.viewStub);
    loadRaiser.Raise(this.viewStub, EventArgs.Empty);
    this.repository.VerifyAll();
}

There are a few subtle differences from the original attach to load event test. I am now using a stub for the view, I set an expectation on the load event in order to get the event raiser, which I have called loadRaiser. This expectation on the stub will never be verified, meaning that the test is more robust to refactoring. I then set the expectation on the service that its’ GetById(4) is called finally setting the repository into replay mode. As in the attach test above, I instantiate the Presenter with the serviceMock and the viewStub. I then use the loadRaiser to Raise the load event, finally verifying that all expectations have been met. The implementation of the constructor now looks like this;

public CustomerPresenter(IService<Customer> service, ICustomerView view)
{
    this.Service = service;
    this.View = view;
    this.View.Load += ((sender, args) => service.GetById(4));
}

Conclusion

As I said from the outset, it is not straight forward, but my hope is that this series will be useful for those of you that wish to go down the route of incorporating dynamic mocking frameworks into your unit tests. This article should help you to avoid some of the pitfalls I went through in trying to understand the feedback from the framework. It should also go some way to convincing you that Rhino mocks gives you a lot of useful features to help you avoid the task of rolling your own fakes.

In the next article I will be writing about some of the new features in Rhino Mocks 3.5 beta and also comparing it with Moq to see which side of the religious argument I fall under.

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

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 »