Ayende @ Wiki

There are basically three different ways of using Rhino Mocks, coming with their own advantages and disadvantages.

Edit

The Standard Syntax

The standard syntax 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 not 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 comments are considered to be a code smell.

Edit

The Record/Replay Syntax

Another way of expressing the codes intend can be achieved with 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 has been done with the comments before, is now replaced by "using (mocks.Record())" and "using (mocks.Playback())". This way the code became much more readable, by explicitly expressing its intend. Another advantage of this syntax is, that ReplayAll() and VerifyAll() are implicitly called.

Edit

The Fluent Syntax

With Rhino Mocks 3.2 came 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.

However, as of C# 3.0, Lambda can be used where delegate is used above. It makes the syntax slightly more tolerable. In this example the word 'delegate' above is replaced with '() =>'

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();

With.Mocks(mocks).Expecting(() => { Expect.Call(dependency.GetSomething("parameter")).Return("result"); dependency.DoSomething(); }) .Verify(delegate { Subject subject = new Subject(dependency); subject.DoWork(); });


Edit

Conclusion

To draw a conclusion, the Record-Playback as well as the fluent syntax are much more readable and decrease the human error factor by implicitly calling ReplayAll() and VerifyAll(). The fluent "With.Mocks(...).Expecting(...).Verify(...)"-way is especially for less complex expectations a fast and easy way to describe expectations and verify code. When more complex expectations have to be configured or the code to be verified is more complex, the Record-Playback syntax might be more handy. But that's mainly a matter of taste.

The advantages of the Record-Playback and the fluent syntax don't make the standard syntax obsolete. There are always cases, when it might fit better. Especially when the test doesn't follow the Expect/Verify pattern, e.g. when Rhino Mocks is only used for stubbing:

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.DynamicMock<IDependency>();

SetupResult.For(dependency.GetSomething("")).Return("result"); mocks.ReplayAll();

Subject subject = new Subject(dependency); subject.DoWork();

ScrewTurn Wiki version 2.0 Beta. Some of the icons created by FamFamFam.