我在使用ref
参数存根方法时遇到问题
我想为某个输入值存根该方法并检查它是否被调用
我的尝试:
// 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:我知道,这个测试没有任何意义,因为它不测试任何真正的类。这是我真实测试的浓缩版本,用于说明问题。
正如你所看到的,有一些奇怪的事情发生了:
执行方法的存根是正确的并且被调用,因为executeCalled
为1且tmp
参数已从inputValue
更改为outputValue
。
但是:
AssertWasCalled
进行的第一次检查,虽然检查了Execute
是否使用 outputValue 进行了调用,但不是。< / LI>
AssertWasCalled
错误进行的第二次检查虽然检查了Execute
是否使用 inputValue 进行了调用,但确实如此。此外,当我检查存根中i.Arguments[1]
内的WhenCalled
时,它是outputValue
,而不是inputValue
...看起来Rhino Mocks正在更改输入值甚至在调用存根之前指定的返回值...
这是Rhino Mocks中的错误吗?或者我错过了什么?如果是错误,是否有executeCalled
计数器旁边的解决方法?
答案 0 :(得分:2)
同样的测试,有点清理:
public interface IX
{
void Execute(ref object param);
}
[TestMethod]
public void TestMethod()
{
// Variables needed - can be skipped
var inputValue = new object();
var outputValue = new object();
IX activity = MockRepository.GenerateMock<IX>();
// The stub:
activity
.Stub(x => x.Execute(
ref Arg<object>.Ref(Is.Same(inputValue), outputValue).Dummy));
var tmp = inputValue;
activity.Execute(ref tmp);
activity
.AssertWasCalled(x => x.Execute(
ref Arg<object>.Ref(Is.Same(outputValue), null).Dummy));
}
它过去了。它清楚地表明Rhino记录的是输出值,而不是原始输入值。它很少被识别,因为您需要此临时变量来测试此效果。
以下测试也通过:
[TestMethod]
public void TestMethod()
{
// Variables needed - can be skipped
var inputValue = new object();
var outputValue = new object();
IX activity = MockRepository.GenerateMock<IX>();
// The stub:
activity
.Stub(x => x.Execute(
ref Arg<object>.Ref(Is.Same(inputValue), outputValue).Dummy));
activity.Execute(ref inputValue);
activity
.AssertWasCalled(x => x.Execute(
ref Arg<object>.Ref(Is.Same(inputValue), null).Dummy));
}
它可以被视为一个错误,但是非常微妙的情况。如果确实存在问题,您可以查看Rhinos代码以查看该错误是否易于修复。