Reading Code: Rhino Mocks
I spent a bit of time recently reading through some of the Rhino Mocks to get a basic understanding of how some features work under the hood.
As well as just getting some practice at reading unfamiliar code I also wanted to know the following:
-
How does the 'VerifyAllExpectations' extension method work?
-
What’s the difference between the 'GenerateMock' and 'GenerateStub' methods on MockRepository?
-
How does the 'AssertWasNotCalled' extension method actually work?
These are some of the things I learnt from my exploration:
-
I’m using a Mac so I originally started out trying to read the code in TextMate with the C# plugin before eventually realising that I couldn’t really tell the difference between a delegate being passed around the code and a method call so I wanted an editor that would help me out with this. I decided to try out MonoDevelop to see if I could keep on reading the code outside my VM. Unfortunately I kept making that crash every time I tried to move between classes so back to Visual Studio it was! MonoDevelop looks like quite a nice tool but it just isn’t for me at the moment.
-
I’ve been playing around with an idea adapted from Michael Feathers' Working Effectively With Legacy Code by drawing out the different classes and how they interact with each other. Where I could see a grouping between classes I’ve been drawing that into the diagram as well. Some of the guys on Twitter showed me a cool web based tool at yuml.me that allows you to easily draw class diagrams and then grab the png/jpeg file and do whatever you want with it. Although these diagrams are quite simple I find them more useful than I had expected and I’ve started drawing more diagrams at work to help understand bits of code that I’m not very familiar with. I realised a couple of years ago when reading one of Scott Young’s posts about drawing diagrams that I seem to understand ideas more quickly if I’m able to draw them out so I should probably look to do it more frequently!
-
The way that stubs and mocks are generated is essentially the same which I’m told is also the case with Mockito although I haven’t read Mockito’s code yet. 'GenerateMock' eventually calls this bit of code: ~csharp public T DynamicMock
(params object[] argumentsForConstructor) where T : class { if (ShouldUseRemotingProxy(typeof(T), argumentsForConstructor)) return (T)RemotingMock(typeof(T), CreateDynamicRecordState); return (T)CreateMockObject(typeof(T), CreateDynamicRecordState, new Type[0], argumentsForConstructor); } ~ 'GenerateStub' eventually calls this bit of code: ~csharp public object Stub(Type type, params object[] argumentsForConstructor) { CreateMockState createStub = mockedObject => new StubRecordMockState(mockedObject, this); if (ShouldUseRemotingProxy(type, argumentsForConstructor)) return RemotingMock(type, createStub); return CreateMockObject(type, createStub, new Type[0], argumentsForConstructor); } ~ The main difference is that when the 'Verify' method is called on stubs (which would call the 'StubReplayMockState' class) we don’t do anything whereas with mocks a check is done to ensure that all the expectations setup in the test are met. I found it quite interesting that the new 'Arrange-Act-Assert' style syntax has been written to make use of the older 'Record-Replay' syntax which I guess is quite a nice metaphor for the two states that you use the framework. I haven’t looked at the Moq code yet but it would be interesting to see how the code for that differs as it was built from the ground up with the 'Arrange-Act-Assert' syntax.</li> The 'AssertWasNotCalled' method works fairly similarly to how I had imagined at a high level in that it goes and gets all the expectations for the mock for that method call and then checks that they aren’t called although I found the implementation of that first bit quite interesting. ~csharp private static ExpectationVerificationInformation GetExpectationsToVerify (T mock, Action action, Action<IMethodOptions
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.