I have problems with stubbing a method with a ref parameter.
I want to stub that method for a certain input value and check that it was called.
My attempt:
// Variables needed - can be skipped
var activity = MockRepository.GenerateMock<ICompositeActivity<object>>();
var context = new Context<object>(new object());
var inputValue = MockRepository.GenerateMock<IActivity<object>>();
var outputValue = MockRepository.GenerateMock<IActivity<object>>();
var executeCalled = 0;
// The stub:
activity.Stub(
x =>
x.Execute(Arg<Context<object>>.Is.Same(context),
ref Arg<IActivity<object>>.Ref(Is.Same(inputValue), outputValue).Dummy))
.WhenCalled(i => ++executeCalled).Return(true);
var tmp = inputValue;
tmp.ShouldBeTheSameAs(inputValue);
// The execution:
activity.Execute(context, ref tmp);
// The check:
inputValue.ShouldNotBeTheSameAs(outputValue); // Passes, ok
tmp.ShouldBeTheSameAs(outputValue); // Passes, ok
executeCalled.ShouldEqual(1); // Passes, ok
// Passes. Why?
activity.AssertWasCalled(
x =>
x.Execute(Arg<Context<object>>.Is.Same(context),
ref Arg<IActivity<object>>.Ref(Is.Same(outputValue), null).Dummy));
// Doesn't pass. Why?
activity.AssertWasCalled(
x =>
x.Execute(Arg<Context<object>>.Is.Same(context),
ref Arg<IActivity<object>>.Ref(Is.Same(inputValue), outputValue).Dummy));
BTW: I know, that this test doesn't make any sense, because it doesn't test any real classes. It's a condensed version of my real test to illustrate the problem.
As you can see, there is something strange going on:
The stub of the execute method is correct and it is called, because executeCalled is 1 and the tmp parameter has been changed from inputValue to outputValue.
BUT:
- The first check with
AssertWasCalledpasses, although it checks, whetherExecutewas called with outputValue, which it wasn't. - The second check with
AssertWasCalledfailes, although it checks, whetherExecutewas called with inputValue, which it was.
Furthermore, when I check i.Arguments[1] inside WhenCalled of the stub, it is outputValue, not inputValue... It looks like Rhino Mocks is changing the input value to the specified return value, before even calling the stub...
Is this a bug in Rhino Mocks? Or am I missing something? If it is a bug, are there any workarounds, beside the executeCalled counter?