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?

Rhino Mocks

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: