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.:
Mock(s => s.SaveNewTimesheet(
Which is much better than:
Mock(s => s.SaveNewTimesheet(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!