2

我在使用参数存根方法时遇到问题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参数已从 更改inputValueoutputValue
但:

  • 第一次使用AssertWasCalled pass进行检查,尽管它检查是否Execute使用outputValue调用,但不是。
  • 第二次检查失败,尽管它检查是否被 inputValue 调用AssertWasCalled 是。Execute

此外,当我检查存根i.Arguments[1]内部WhenCalled时,它是outputValue,不是inputValue......看起来Rhino Mocks正在将输入值更改为指定的返回值,甚至在调用存根之前......

这是 Rhino Mocks 中的错误吗?还是我错过了什么?如果它是一个错误,在executeCalled柜台旁边是否有任何解决方法?

4

1 回答 1

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 代码,看看该错误是否易于修复。

于 2011-04-19T14:45:17.817 回答