It's now about a year ago, that I've started to use Rhino Mocks for my mocking needs in .NET development. In the beginning I didn't liked it very much. This was mainly because of its Expect-syntax:
Expect.On(subject).Calls(subject.SaveTheWorld()).Returns(False);
When getting in touch with Rhino Mocks the first time, I wasn't won over by this "wanna be a real English sentence" approch, nowadays called "fluent interface". But on the other side Rhino Mocks had some nice features, I really liked. Espeacially it's easy way of dealing with generics has been decisive to give it a chance. It certainly wasn't a love at the first sight, but today I wouldn't miss it anymore.
There are basically three different ways of using Rhino Mocks, coming with their own advantages and disadvantages. Everybody knows the standard way of working with Rhino Mocks, but I have the feeling, that the other two Rhino Mocks syntaxes are a little bit unappreciated or not very well known. I hope to give you an understanding of the alternative Rhino Mocks syntaxes, but let's start with the standard, which looks like this:
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
mocks.ReplayAll();
Subject subject = new Subject(dependency);
subject.DoWork();
mocks.VerifyAll();
The above code basically sets up a mock for the IDependency interface, that gets passed into the Subject class. Two expectations are then defined for the mock. The first expects the GetSomething() method to be called with a parameter and returning a value. The second expects the void method DoSomething() to be called. After calling subject.DoWork(), it is verified with mocks.VerifyAll(), if all the expectations on the mock have been met.
It's only eight lines of code, but I don't consider this very readable. Some comments and empty lines can help here:
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
// define expectations
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
mocks.ReplayAll();
// run test subject
Subject subject = new Subject(dependency);
subject.DoWork();
// verify expectations
mocks.VerifyAll();
This looks better, but as we all know, comments are a code smell, so let's take a look at another way of expressing our intend, by using Rhino Mocks' "Record-Playback" syntax:
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
using (mocks.Record())
{
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
}
using (mocks.Playback())
{
Subject subject = new Subject(dependency);
subject.DoWork();
}
What we've done with the comments before, is now replaced by "using (mocks.Record())" and "using (mocks.Playback())".
It might be a matter of taste, but I find this much more readable. Another advantage of this syntax is, that ReplayAll() and VerifyAll() are implicitly called. I can't count the number of times, I missed one of these calls and then wondering, why the test doesn't work.
Recently introduced in Rhino Mocks 3.2 comes another syntax, which tries to follow the "fluent interface" methodology:
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();
With.Mocks(mocks).Expecting(delegate
{
Expect.Call(dependency.GetSomething("parameter")).Return("result");
dependency.DoSomething();
})
.Verify(delegate
{
Subject subject = new Subject(dependency);
subject.DoWork();
});
Again ReplayAll() and VerifyAll() are implicitly called, eliminating a big possible cause of failure. One advantage over the Record-Playback syntax is it's fluent interface. Intellisense will guide you step by step, each time you type the ".". A small drop of bitterness is the usage of anonymous delegates. The delegate keyword always looks kinda "noisy" to me, but that's something I can live with.
To draw a conclusion, I think the Record-Playback as well as the fluent syntax are much more readable and decreases the human error factor by implicitly calling ReplayAll() and VerifyAll(). This makes me prefer these syntaxes over the standard way most of the time. Usually I now use the fluent "With.Mocks(...).Expecting(...).Verify(...)"-way for easy to set up expectations. When more complex expectations have to be configured or the code to be verified is more complex, I find the Record-Playback syntax more handy.
I rarely use the standard syntax nowadays. When I'm using it, then mostly for setting up simple stubs like this:
MockRepository mocks = new MockRepository();
IDependency dependency = mocks.DynamicMock<IDependency>();
SetupResult.For(dependency.GetSomething("")).Return("result");
mocks.ReplayAll();
Subject subject = new Subject(dependency);
subject.DoWork();
For a complete description of the different Rhino Mocks syntaxes, take a look at its documentation.




