RhinoMocks
August 17, 2010 Leave a comment
I am digging deeper into fakes using RhinoMocks. I set up a test project that uses a Mock of an InterfaceKit and then sets up some expected return values. For example:
[TestInitialize()]
public void InterfaceKitTestInitialize()
{
MockRepository mockRepository = new MockRepository();
interfaceKit = mockRepository.StrictMock<IInterfaceKit>();
Expect.Call(interfaceKit.Address).Return("ValidAddress");
mockRepository.ReplayAll();
}
And a subsequent test:
[TestMethod()]
public void InterfaceKitAddress_ReturnsValidValue()
{
string expected = "ValidAddress";
string actual = interfaceKit.Address;
Assert.AreEqual(expected, actual);
}
So far so good – it comes back green. But then I thought “So what?” All I am really doing is testing the Mock API. Unless there is some business logic in the getter, then mocking properties are useless. I guess you would use a mock over a stub because you can control the number of properties that you need to test – you don’t have to set up a whole object graph if you just want to test 1 property.
I also noticed that I could use this syntax instead of using Expect.Call:
SetupResult.For(interfaceKit.Address).Return("ValidAddress");
I then tried to venture on to mock a method. I attempted to add a new line to my initialization method like this:
Expect.Call(interfaceKit.open());
However, I am getting some errors:
I then realized that I had a syntax error for parameter-less methods:
Expect.Call(interfaceKit.open).Return(null);
This works – but I am not testing anything. So I thought a bit more – why would you even mock a method that does not return a value and does not take a parameter? Unless there is another dependency that the method needs to run (for example, setting a property of the object before calling the method) and the only way you know if it ran was if you got an exception, there is no point.
Expect.Call(interfaceKit.open).Throw(new PhidgetException(ErrorType.PHIDGET_ERR_CLOSED));
I guess this is what they mean when they say that mocking and unit testing forces you to make a better API. The Phidget kit does this (open then wait for the event). I then made a test to check the exception
[TestMethod()]
[ExpectedException(typeof(PhidgetException))]
public void InterfaceKitAttachedTest_ThrowsError()
{
interfaceKit.open();
Assert.Fail("Should never get here");
}
and the test passed. If I wanted to test the value of the ErrorType, I would put it into a try..catch block in the test and inspect the PhidgetException.ErrorType property and remove the ExpectedException attribute.