TDD – Rhino Mocks – Part 1 – Introduction

Mocking is term which describes programing technique mostly used in Test Driven Development for writing tests of some entity with abstraction of its dependencies.

The best example is MVP design pattern where we are implementing presenter code by using Dependency Injection pattern to inject in presenter view implementation and maybe data source implementation during the run time.

In my last post I provide MVP & TDD Example source code where in RateCardPresenter.cs there’s next constructor:

public RateCardPresenter(IRateCardView view, IRateCardDataSource dataSource)
{
      _view = view;

      _dataSource = dataSource;

      Initialize();
}

In old days if I would like to mock data source in case when there’s no *real* object, I would have to create static mock type interface implementation which would be something like:

internal class RateCardDummyDataSource : IRateCardDataSource

{

 

      #region IRateCardDataSource Members implementation

     

      #endregion
}

Problem with that implementation is that in real world scenarios results with swarms of dummy mock object which are useless once after the real implementation is been done and causes very big maintenance problems. Static mocks are maybe main reason why TDD didn’t take the place which deserves in development methodology

Mocking frameworks

That problem  is been solved by couple of dynamic mocking frameworks such as: NMockEasyMock.Net and my personal champion: Rhino mocks. They all use Proxy design pattern to create on the fly mock object which is implementing given interface. Advantage of RhinoMock is that has a lot of features: different mocking creation methods, enables usage of intellisense on mocked objects, explicit recording mode etc.

Rhino mocks explained in one sentence could (maybe) be: first we enlist (“record”) everything we expect it would happened and then, after recording, we just check if our expectations were met.

Dynamic mocking

So in our case, mock creation of IRateCardDataSource with Rhino mocks would be simple:

 

private MockRepository _mockery;

private IRateCardDataSource _dataSource;

 

 

[SetUp]

public void InitTest()

{

      _mockery = new MockRepository();

      _dataSource = _mockery.DynamicMock<IRateCardDataSource>();

}

(For now, you can think about MockRepository as a kind of helper class which exposes Rhino mocks methods)

By implementing that single line we have now _dataSource object which implements IRateCardDataSource and which we can use in our unit tests.

But, this object is just a shell of the real object a kind of
spy which imitates real object and tell us: “Hey, someone set on me property X and then call method Y”. There’s no data inside at all. I believe you would be asking by now what is the benefit of using that kind of mock (“Data source without the data is useless”).

TDD behavioral tests

In TDD, one of the main principles is writing the tests for certain part of the code, before the code is been implemented. That it is been done because test in TDD world is a kind of contract on desired behavior of the code tested. So, when I’m writing tests for my presenter methods before they exist I care to define presenter behavior and not data source behavior. I could say that I expect that inside of the presenter certain method would call datasource object and get some results. I don’t care how datasource would get that data and (for now) what kind of data it would be returned. I just care about contracting presenter behavior. Something like:

 

// expect first call to data service which would

// return some rate card items

Expect.Call(_dataSource.GetRateCardData(rateCardTypeID))

      .Return(rateCardItems);

// expect that the view ratecarditem collection

// would be set to the result of data service

_view.RateCardItems = rateCardItems;

 

As you can see, I used mocked data source object to put expectation that somewhere inside of presenter presenter would call datasource method and expectation that those results would be set then on view dynamic mock object property.

How this works: _dataSource and _view are “spays” which would tell to rhino mocks framework if the expected action on their method happened or not. If not Rhino mock would throw an exception which would be cached by NUnit and the test would fail.

Recording modes

In our previous example, if we would implement the presenter code on the way that _view would be set before the datasource would be called, both test would pass because both of the spays would report that their expectations were fulfilled.

That’s why in RhinoMocks we can set Mockery to direct mocking spays to check if the expectations happened in order given while we record our expectations. Something like:

using (_mockery.Ordered())

{

      // expect first call to data service which would

      // return some rate card items

      Expect.Call(_dataSource.GetRateCardData(rateCardTypeID))

            .Return(rateCardItems);

      // expect that the view ratecarditem collection

      // would be set to the result of data service

      _view.RateCardItems = rateCardItems;

}

Which would cause our test failing if the expectations were not met in order they were recorded.

The default behavior of the recording mode is Unordered, but you can combine “group” the expectations whatever you prefer. Something like:

// default recording mode. Using block can be omitted

using (_mockery.Unordered())

{

      //expect that header message would be set to

      // header message of contract rate card

      _view
.HeaderMessage =

      Constants.HEADER_MESSAGE_CONTRACT_CART;

     

      using (_mockery.Ordered())

      {

            // expect first call to data service which would

            // return some rate card items

            Expect.Call(_dataSource.GetRateCardData

           (rateCardTypeID)).Return(rateCardItems);

 

            // expect that the view ratecarditem collection

            // would be set to the result of data service

            _view.RateCardItems = rateCardItems;

      }

}

Which would mean: I don’t know if the header message would be set before the ratecard data source group of expectation or after, but I do expect that whenever datasource group expectations would start, they would execute in expected order.

Setting up mock values

Well, for certain presenter action could depend on certain mock object values, so for some test we would have to set the view to desired state (“set up the stage for recording”)

We can do that by setting expectations like:

Expect.Call(_view.RateCardProductType).Return(1);

Which means: When presenter would check the view RateCardProductType property of the mock he should get the value of 1 from the mocked object (“spy would report 1”)

By default all of the expectations are single expectations, so if presenter would try to get that value for the second time somewhere in the code he would get null value.

But that breaks the concept of the black box presenter implementation in the moment of writing tests, so in case when I don’t expect exactly one call, I’m usually using multiply value setting retrieval expectations. Something like:

Expect.Call(_view.RateCardProductType).Return(1).
      Repeat.AtLeastOnce();

which offers much more customization over the preoperative expectations

or simple

SetupResult.For(_view.RateCardProductType).Return(1);

Both of them are the same: Whenever someone asks for RateCardProductType returns him 1.

Play!

End of the recording mode is been signalized to MockeryType by simple call of ReplyAll() method. Results of every line after that are been compared with the spy expectations until the MockeryType.VerifyAll() method call when the successfulness of the expectations fulfilling is been examined and the success/fail result is been propagated to NUnit framework as a passed/failing test. Something like this

// default recording mode. Can be omitted

using (_mockery.Unordered())

{

      //expect that header message would be set to

      // header message of contract rate card

      _view.HeaderMessage =

           Constants.HEADER_MESSAGE_CONTRACT_CART;

     

      using (_mockery.Ordered())

      {

            // expect first call to data service which would

            // return some rate card items

            Expect.Call(_dataSource.GetRateCardData

                (rateCardTypeID)).Return(rateCardItems);

            // expect that the view ratecarditem collection

            // would be set to the result of data service

            _view.RateCardItems = rateCardItems;

      }

}

 

// stop recording actions and start verify mode

_mockery.ReplayAll();

 

// init presenter class

RateCardPresenter presenter =

      new RateCardPresenter(_view, _dataSource);

 

// propagate to Nunit status of behavioral expectations

_mockery.VerifyAll();

 

 

Conclusion

 

That would be all for now – I hope you’ve got the big picture which was the point of this intro article 🙂

 

Next parts of Rhino mock article series would cover in more details every aspect of rhino mocks framework + some of my real world “gotcha type” experiences in using it

 

Update: Part 2 of the rhino mock can be found here Rhino Mock Part 2 – Common scenarios

 

 

Share this post :

Posted on February 5, 2007, in Uncategorized. Bookmark the permalink. 7 Comments.

  1. Nikola,

    Thanks for the series – it's been very helpful.

    Can you tell me what are "spays"?

    Thanks

  2. Lars,
    It was just me misspeling words 🙂
    Spay => spy
    (Proxies are spying and reporting events occurring on mocks)

  3. Hi…
    Have you heard about Typemock.
    Using Typemock Framework you do much more. For example:
    mock static methods and more – see the site.
    Also you do not have to "wrap" methods to interfaces

  4. Menahem,
    I have heard and work with it a bit but the experience of working with it without NaturalMock is much worst (no strong typing) then the Rhino Mock experience…
    I am aware of things you can do with TypeMock  but the price (comparing to the fact that RhinoMocks are free) is "no sell" point for me

  5. Have you heared about the new Typemock API?

  6. Menahem,
    I’ll admit it’s been a while I’ve checked out TypeMock but if they improve the "free user experience" by adding some strong typing feature I would be glad to give it a shoot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: