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
AssertWasCalled
passes, although it checks, whetherExecute
was called with outputValue, which it wasn't. - The second check with
AssertWasCalled
failes, although it checks, whetherExecute
was 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?