Ayende has again proven why he is one of the most respectednames in Alt.Net community. Besides writinga book on language based DSLs, supporting Boo, and NHibernate, having a fulltime job, and writing one of the most informative blog publications, he hasactually practically re-written RhinoMocks in this new version. And with that RhinoMocks basically takes backthe title of simplest and most productive dynamic mocking framework out there.
Take a look at an ASP.NET MVC test written with RhinoMocks3.3:
As you can see the test above uses a traditional Record& Replay model (referred to as R&P in the rest of this document), wherein Record block we generally set our expectations, and then the Replay block isused to perform actions on object being tested, allowing our Mock objects to execute and verify expectations.
Now let’s take a look at the same test written withRhinoMocks 3.5:
This test uses Arrange, Action and Assert model (AAA). What you will notice first is that there areby far fewer lines needed to setup mocks.
In the AAA version there is no need to instantiateMockRepository, once you generate your Mock, or in this case Stub object, youcan setup your expectations directly on the mock instance. Lines 21 and 22 inR&P version of the test are replaced by single line of code in AAA version –line 22.
You will also notice that we are using GenerateStub()instead of DynamicMock(). Put simply thereis a difference between Mock and Stub objects and RhinoMocks recognizes thatallowing us to write tests that better state their purpose. For some of you scratching your heads,easiest way to describe the difference is to say that Mock objects are used todefine expectations i.e: In this scenario I expect method A() to be called withsuch and such parameters. Mocks recordand verify such expectations. Stubs, onthe other hand have a different purpose: they do not record or verifyexpectations, but rather allow us to “replace” the behavior, state of the “fake”object in order to utilize a test scenario.
In this case the behavior we want to stub is: “WhenGetCustomers() is called return the testCustomers list.” You can see that AA version uses a Lambda expressionto define the method being called. Againthe line 24 in AA version replaces lines 24-30 in R&P version.
And lastly at the end of the AAA version, as we have definedour expectation directly on the mock object itself (which replaced the recordblock), there is no need to define the Playback block either. It is assumed that it follows the recordedassumptions. Therefore the Playbacksection of the R&P model is comparable to Action and Assert sections of theAA model.
So as you can see our tests have dropped from 13 down to 7lines of code. Also due to a lot simplermocking portion of the block tests are now lots easier to read and maintain. I must add that this is only the portion ofthe new features Ayende is adding to RhinoMocks, and for more details I wouldrefer you to go to RhinoMocks wiki as well as Ayende’s blog. Personally I would like to congratulate himon making a good Dynamic Mocking tool great.