Friday, August 7, 2009

Arguments in Stubs and mocks

Below is an informal email to work mates. Please note I am not the boss, I am a lowly contractor at the bottom of the heap, The devs I work with have a refreshingly open communication channel and I tend to have a bit more experience in Testing/TDD

*****
Hey Guys
I think I have unfortunately let some bad habits of mine slip over to you guys.

Some basic rules of thumb:

-Stubs should be used by default to isolate dependencies, use mocks when you are mandating that the SUT is incorrect if it does not interact with the given dependency.
-I will often declare in a test method set up the class level dependency to be a mock (with associated verify in the tear down), however that does not need to have expectations. You can always use the stub method on a mock, meaning failure to call that method will not fail the test.
-Use correct arguments and return values. Returning null and using the .IgnoreArguments() method should be last resorts and are generally a sign (if it is my code) of laziness or haste. Don’t do it unless it actually makes sense for the test.
-When returning null from a stub or mock the SUT should be handling it properly. I.e. what if that dependency actually did pass back a null? Is that even valid? Should we be handling it?

The major problem I find is the ignore argument method, I abuse it far too much when mocking, and I see it creeping it others work (not just ours but external code too!). Note: Ignore Arguments on stubs is not so bad, as a stub should not fail a test

RhinoMocks has the ability to specify argument placeholders that do not have to be the exact reference type that is being used e.g.:

timesheetService.
Mock(s => s.SaveNewTimesheet(

Arg.Is.Equal(creationDto)
))
.Return(new TimesheetDetailsDto());


Which is much better than:

timesheetService.
Mock(s => s.SaveNewTimesheet(null))

.IgnoreArguments()
.Return(null);


Be sure to override the equals method to accurately reflect the equality tho, otherwise the default of reference equality will still cause the test to fail!

No comments: