My Lessons Learned From Rhino.Mocks

Recently I have begun working with Rhino.Mocks and I stumbled a little bit getting up to speed. My experience with mocks is from using JMock1 with a Java project. This is the first time I have used mocks on a .NET project so it took me a little bit getting used to the syntax.

From looking at all the tutorials and examples on the web about Rhino.Mocks I couldn’t really find anything that was a kick in the pants from my stand point. Most of the tutorials didn’t discuss the methods Rhino.Mocks framework in any detail, and would instead go into, somewhat, depth about the theory of mocking. I already know (or at least think I do) the theory of mocking so I was really wanting something to get me going quickly.

I found a video by the creator of Rhino.Mocks, Ayende, which really helped out. I wanted to put up here some of the key points. You can watch the video at http://www.ayende.com/hibernating-rhinos.aspx.

The ‘_mocks’ variable listed below is a reference to the mocks repository, this will basically contain all of your mocks:

var \_mocks = new MockRepository();

The ReplayAll method, _mocks.ReplayAll(), puts the framework into record mode. You will need to call this method after creating your mocks and setting expectations. The Rhino.Mock framework will begin to track all the method calls and verify the expected counts (if any) are meet. In the video Ayende talks about this around 11:08, 28:10 & 29:50. There is not any issue with calling this method repeatedly, so having it in your TearDown method as a precaution will not cause any problems.

One other thing that sent me on a wild goose chase is the error message:

require a return value or an exception to throw

This will occur when you don’t move your tests from Record mode to Replay mode (typically you are missing a _mocks.ReplayAll() method call). What happens is you call a method such as ‘user.GetPurchases()’, and in my case I was making an assertion on the expected values. But the framework is waiting on you to specify an expectation or a return value, but since this is missing Rhino.Mocks can not handle it and so throws that exception.

As the name implies ‘_mocks.VerifyAll()’ will verify any outstanding expectations which were set by you, I have this in my TearDown method as well.

What’s the difference between Expect.Call and LastCall.Constraints? As he discusses in the video at 36:55, this is due to a constraint the compiler enforces. If you had the following code:

class User {
  public void Save() { .... }
}

Then of course the compiler will not allow you to have syntax such as:

Expect.Call(user.Save())

You will need a way to execute the call, then set expectations on that … well, last call. Simple name huh? Shockingly he discusses this as well in the video at 36:55. Both of syntaxes are basically the same, the Expect.Call syntax is actually changed into the LastCall format. He shows how to mock out a void return type around 19:40.

Another exception/error you might stumble across is:

This action is invalid when the mock object is in verified state.

You will run across this while trying to setup a mock or expectation and in the record phase. My mistake was putting the creation of the MockRepository instance (the _mocks variable) in the TestFixtureSetup method - being this is only called once per the entire test class, my MockRepository was not being recreated. So I received the error - switching this to be what I expected, the Setup attribute, then all was well.

Something I have yet to look into is the difference between the following lines:

Expect.Call(order.PaidInFull).Return(false);

-- and --

SetupResult.For(order.PaidInFull).Return(false);

If you know of what the difference might be, I would be happy to hear.

Related Posts