In Part 4 we looked at how parameter constraints are handled and in Part 3 we looked at how to do interaction based tests with mocks. In this part we bring those two pieces together and add a little extra to check if a call was made a specific number of times.
Let’s just jump straight into the code shall we?
Our test here is simply going to call a method a number of times and verify that the call was made the correct number of times using constraints to verify the correct calls. It’s a completely useless test, other than as a vehicle to show you how to do this sort of thing
public void Rhino_repetitions()
var monkey = MockRepository.GenerateMock<IMonkey>();
monkey.AssertWasCalled(m => m.TryAddFleas(0),
options => options.Constraints(
Is.GreaterThan(3) && Is.LessThanOrEqual(10)
monkey.AssertWasCalled(m => m.TryAddFleas(-1),
options => options.Repeat.Once());
Note the important part, the .Repeat.Twice() and .Repeat.Once() calls. It’s these calls that define our expectations as to how many times the call should have been made.
Rhino also features a .Repeat.Time(n) call you can use as well if once or twice don’t cut it for you.
public void Moq_repetitions()
var monkey = new Mock<IMonkey>();
monkey.Verify(m => m.TryAddFleas(
monkey.Verify(m => m.TryAddFleas(-1), Times.Once());
Instead of using the word Repeat, Moq uses Times. Apart from that there is little difference.
Unfortunately NSubstitute doesn’t support this feature yet as it’s still a maturing framework. If you really need to do this type of testing then you’ve got a few options – use Rhino or Moq, contribute to the NSubstitute project, or to just not do this type of testing :-).
Interaction based testing is valid at times, but it’s generally brittle and is usually a sign of “implementation verifying” tests rather than behaviour/specification verifying tests (but that’s an argument for another time)
Verdict: Moq wins out in this case simply because it’s constraint system is more terse than the Rhino one, but this is purely a personal taste thing.
Other posts in this series:
- 1: The Basics
- 2: Properties
- 3: Interactions
- 4: Parameter Constraints
- 6: Multiple Calls
- 7: Exceptions
- 8: Recursive Mocks
- 9: Functions
- 10: Events
- 11: Multiple Interfaces
- 12: The UnMockables