Mocking frameworks and me
Until recently, mocking frameworks never really clicked in my mind. I understood their purpose, however the terminology really didn’t fit with the idea of mocking to me and the tentative grasp I had on the concept would fall apart when I tried to get the mocking framework up and running in my tests. So for a while I was mocking by hand. Recently, I have been using Rhino Mocks successfully. It has finally made sense to me, and I will mock by hand no longer.
The biggest mistake that I made in trying to understand the Rhino Mocks framework was thinking that all the mocking framework was doing was playing stunt double for the object that it was mocking. Rhino Mocks doesn’t just ’stand in’ for the object you wish to mock, it will verify that methods are called on that object, giving you additional testing power. Once I understood this, it explained the replay and verify terminology I would see in the examples, and things started to fall into place.
Once I had my epiphany about the usage of Rhino Mocks, I went to use it and I was stymied again. I saw that I needed to create a mock object from an interface, but how? And what is the difference between a StrictMock and a DynamicMock? It wasn’t until I read this that I was able to begin actually using the framework.
As it turns out, the difference between a StrictMock and a DynamicMock is pretty simple to understand. As we have seen, a core concept is the recording, playback and verification of method calls on the mock objects. Well what happens if your System Under Test calls a method on the mock object that the mock wasn’t expecting? What happens in this situation is the difference between Static and Dynamic Mock objects. A StrictMock is just that, strict. If a method gets called on a strict mock that it wasn’t expecting, it will let you know with red. Now the terminology here still get me sometimes. I think of the opposite of strict to be lax, forgiving or maybe flexable. Likewise, I think of the opposite of dynamic to be static. In this case, the opposite of strict is in fact, dynamic. If a method is called on a dynamic mock that you didn’t tell it to expect, it just keep trudging along. That’s not to say that it will necessarily return somehting valid, but the fact that the method itself was called isn’t going to turn your test from green to red.
Making a mockery
So how do you actually use this beast? Well it’s quite simple really, once you have all the pieces in place. Having an understanding of interfaces and dependency injection will help get you off the ground here. Let’s set up a couple of classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public class DeathTrap : IDrivable { private int _speed; private bool _brakesFunctional; public DeathTrap() { _speed = 0; _brakesFunctional = true; } public void Accelerate(int amount) { _speed = _speed + amount; // Something really time consuming and irrelevant here } public bool Brake(int amount) { // Something really time consuming and irrelevant here if (amount == 21) { _brakesFunctional = false; } if (_brakesFunctional == false) { return false; } _speed = _speed - amount; } } public interface IDrivable { void Accelerate(int amount); bool Brake(int amount); } public class Driver { private IDrivable _prideAndJoy; public Driver(IDrivable prideAndJoy) { _prideAndJoy = prideAndJoy; } public void Go(int amount) { _prideAndJoy.Accelerate(amount); } public bool Stop(int amount) { return _prideAndJoy.Brake(amount); } } |
Ok so this is a basic driving game where a driver has a DeathTrap that implements IDrivable. If the driver tries to brake by 21 units the brakes will go out and will no longer function. So let’s test Driver and make sure it does what we would expect it to do. First let’s test that when we tell the driver to go, he goes.
1 2 3 4 5 6 7 8 9 10 11 12 | [Test] public void WhenITellADriverToGoTheCarWillBeAccelerated() { mockery = new MockRepository(); //Create an object to hold and manipulate mocks. car = StrictMock<idrivable>(); //Tell Rhino Mocks to make a strict mock from the interface. driver = new Driver(car); // inject the car into the driver via constructor. car.Accelerate(5); // tell the mock to expect a method call to Accelerate with a value of 5. mockery.ReplayAll(); // switch the mocks to replay mode. driver.Go(5); // The actual call. mockery.VerifyAll(); // verify that the expected call was in fact made. } |
As you can see there are a number of things happening here, but it really breaks down to the following.
- Setup Mock
- Hand the mock to the System Under Test
- Tell the mock what call to expect
- Flip the mock framework into replay mode
- Do the stuff you want to test
- Verify that the expected call was made
That wasn’t too bad. Let’s try another example. This one has a slightly different syntax. I could have used a StaticMock here, it really didn’t matter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [Test] public void WhenIPressTheBrakeWithAValueOfTwentyOneItWillReturnFalse() { mockery = new MockRepository(); // Setup our mock repository car = DynamicMock<idrivable>(); //make the mock car driver = new Driver(car); // inject car into our driver Expect.Call(car.Brake(21)).Return(false); //tell our mock to return false when it gets a call to brake 21 mockery.ReplayAll(); // switch to replay mode bool returned = driver.Stop(21); // call the System Under Test mockery.VerifyAll(); // verify that the method on car was called Assert.False(returned); // assert the return value is false } |
The primary difference here is that the method that we are calling returns a value this time. So we have to tell our mock what to return when the method is called. Notice that in both cases of this contrived example, by mocking the car we were able to do three important things.
- Isolate the behavior we were interested in.
- Ensure that the IDrivable returned the value we wanted.
- Avoided having to wait for Something really time consuming and irrelevant to happen.
I hope this helps get you off the ground with using a mocking framework. If I come across any further eureka moments I’ll be sure to post them. Enjoy!
Tags: .NET, mocking, Rhino Mocks, Testing