I'm trying to asssert that a method was called on a stub. The method I'm trying to assert was called takes an IEnumerable<string>
. I don't care about the exact contents, but I just want to test that the count is a certain number. I can't get the assertion correct, I get
Rhino.Mocks.Exceptions.ExpectationViolationException : Bob.DoThings(collection count equal to 10); Expected #1, Actual #0.
I know that DoThings() is indeed being called... I just can't get the constraint correct..
var myBob= MockRepository.GenerateStub<Bob>();
var countConstraint = Rhino.Mocks.Constraints.List.Count(Rhino.Mocks.Constraints.Is.Equal(10));
// execution code....
Joe myJoe = new Joe(myBob);
myJoe.MethodThatShouldCallDoThingWith10();
myBob.AssertWasCalled(s => s.DoThings(null), o => Constraints(countConstraint));
I've also tried adding "IgnoreArguments" as a constraint. What am I missing?
The issue here is with deferred execution. It's not until the IEnumerable<string>
is enumerated that the list of items is "built". Since Rhino.Mocks just records what gets called, it never "uses" the method arguments and therefore, the list is never built nor enumerated. As you've seen, adding a ToList() or ToArray() enumerates and builds the list so the test will pass if you use one of those methods.
One workaround is to grab the list that was passed to the method and do your check on that:
var list = (IEnumerable<int>) myBob.GetArgumentsForCallsMadeOn(b => b.DoThings(null))[0][0];
Assert.AreEqual(10, list.Count());
This test passes and doesn't require any changes to your code.