1

编辑:我玩过这个例子,现在我的问题完全不同了

当我运行这个例子时:

using Rhino.Mocks;

public interface IInterface
{
    decimal GetDecimal();
}

static class Util
{
    public static double? DecToDouble(this IInterface input)
    {
        return (double) input.GetDecimal();
    }
}

class MockExample
{
    public void RunThis()
    {
        var stubReader = MockRepository.GenerateStub<IInterface>();
        stubReader.Stub(sr => sr.DecToDouble()).Return(1.2);
    }
}

我收到此错误:

System.InvalidOperationException:类型“System.Double”与方法“IInterface.GetDecimal();”的返回类型“System.Decimal”不匹配

为什么?

4

2 回答 2

4

Rhino Mocks 只能拦截通过存根接口进行的调用。上面的扩展方法被编译成类似:

Util.DecToDouble(sr)

这意味着您的设置/返回基本上是这样的:

stubReader.Stub(sr => Util.DecToDouble(sr)).Return(1.2);

这显然行不通(对于大多数模拟框架)。实现您想要的正确方法是:

stubReader.Stub(sr => sr.GetDecimal())).Return(1.2);

经过进一步调查: Rhino Mocks 通过调用传递给 Stub() 的委托并保存最后应用的方法调用,将 Stub() 声明的方法内部连接到 Return() 声明的值。这个保存的方法调用随后连接到返回值。执行此操作时,Rhino Mocks 会在内部检查已保存调用的返回类型是否与值的类型匹配。如果它们不匹配,Rhino Mocks 会引发您所看到的异常。定义存根的正确方法是

    decimal val = 1.2M;
    stubReader.Stub(sr => sr.DecToDouble()).Return(val);

但这不会编译,因为 Stub() 和 Return() 的泛型类型参数必须兼容。所以真正定义存根的唯一方法是忽略扩展方法,只存根接口中定义的方法。

于 2013-07-15T18:47:07.297 回答
0

如果您尝试模拟,IInterface那么您正在使用错误的方法:

public void RunThis()
{
    var stubReader = MockRepository.GenerateStub<IInterface>();
    stubReader.Stub(sr => sr.GetDecimal()).Return(1.2);
}

如果你想存根DecToDouble,你不能用 RhinoMocks。扩展方法被编译为静态方法调用,RhinoMocks 无法模拟这些方法调用,因为它们是在编译时绑定的。一些存根框架使用低级分析器调用来拦截静态调用,但 RhinoMocks 没有我所知道的那种能力。

有关类似讨论,请参阅此问题。

于 2013-07-15T18:08:54.623 回答