A few days ago, I read Kyle Baley’s post about learning Rhino Mocks. Like many folks, he initially had trouble understanding Rhino Mocks’ record/playback metaphor. Then during the Calgary Code Camp, an attendee kindly pointed out that I had forgotten mockRepository.ReplayAll() in my unit test – fortunately before I actually ran it. Then yesterday I was catching up on my blog reading and saw this post from Oren discussing various people forgetting to call mockRepository.ReplayAll(), including Oren himself.
I thought to myself, Rhino Mocks has a very nice fluent interface, but doesn’t make its Record/Playback explicit. What would I want my code to look like if it did support explicit Record/Playback? So I grabbed the source from Subversion, put on my TDD hat, and came up with this failing test:
[Test]
public void CanRecordPlayback() {
MockRepository mockRepository = new MockRepository();
IFoo mockedFoo = mockRepository.CreateMock<IFoo>();
using(mockRepository.Record()) {
Expect.Call(mockedFoo.Bar()).Return(42);
}
using(mockRepository.Playback()) {
Fooz fooz = new Fooz(mockedFoo);
fooz.Barz();
}
}
A few minutes later, I had working code for the Record and Playback methods, all the unit tests passed, I created a patch, and emailed it to Oren for his thoughts on the new syntax. He liked it so much that he included the new syntax in Rhino Mocks 3.0.5, which he just released today.
A few things to note about the new syntax. Expectations are grouped in the Record block. Exercising the mocks occurs in the Playback() block. ReplayAll() and VerifyAll() are called implicitly after the Playback() and Record() blocks, respectively.
Time between initial idea and production deployment: Less than 24 hours. How is that for great turn-around? Thanks, Oren. I’m proud to have committed to such a widely-used (and respected) project!