打桩静态扩展方法似乎犀牛制品工作,除非我投返回变量。为什么? [英] Stubbing a static extension method seems to work in Rhino Mocks unless I cast the return variable. Why?

查看:276
本文介绍了打桩静态扩展方法似乎犀牛制品工作,除非我投返回变量。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够使用存根犀牛制品的静态扩展方法,但如果我将返回值转换为另一种类型,我得到一个错误。为什么?



 使用Rhino.Mocks; 

公共接口INumberGenerator
{
双GetDouble();
}

静态类NumberGeneratorExtensionMethods
{
公共静态双GetTheDouble(此INumberGenerator输入)
{
返回input.GetDouble();
}

公共静态十进制GetTheDoubleCastToDecimal(此INumberGenerator输入)
{
回报(十进制)input.GetDouble();
}
}

类MockExample
{
公共无效TriggerTheError()
{
VAR存根= MockRepository.GenerateStub< INumberGenerator>();

//此工程
stub.Stub(OBJ => obj.GetTheDouble())返回(1.2D)。

//这引发错误
stub.Stub(OBJ => obj.GetTheDoubleCastToDecimal())返回(1.2米)。
}
}

下面是错误:




System.InvalidOperationException:类型System.Decimal不适用于匹配方法的返回类型'System.Double'INumberGenerator.GetDouble();



解决方案

警告:这是一个真正的怀疑比什么都重要



的问题是,你没有的真正的存根扩展方法在所有 - 你删 GetDouble 在这两种情况下。



我没有看过的犀牛制品的代码一段时间,但我的犯罪嫌疑人的那在存根方法基本上是说:




  • 准备好上模拟一些调用!

  • 调用传递作为参数

  • 的委托注意它要求作了



这意味着你有效地这样做:

  canGetDecimal.Stub(纳克=> ng.GetDouble())返回(1.2D)。 
canGetDecimal.Stub(NG =>(十进制)ng.GetDouble())返回(1.2米)。



在这一点上,它会注意到你叫 GetDouble - 但是你要设定的返回值,达120万,这是无效的。



您可以验证这很容易地,一些记录。日志行添加到 GetTheDoubleCastToDecimal ,然后拆出从返回存根通话code>电话:

  Console.WriteLine(以前存根); 
VAR stubCall = canGetDecimal.Stub(OBJ => obj.GetTheDoubleCastToDecimal();
Console.WriteLine(存根后);
stubCall.Return(1.2米);

我强烈怀疑你会发现,无论你记录加入到扩展方法仍然登录以前存根之间以及存根后 - 这表明扩展方法的的被嘲笑了。



道德:唐T试图模拟/存根扩展方法他们是不是多态;。他们只是静态方法,这将是相当棘手假冒他们不深的魔法,只有尝试假了真正的多态操作


I am able to stub a static extension method using Rhino Mocks but if I cast the return value to another type, I get an error. Why?

using Rhino.Mocks;

public interface INumberGenerator
{
    double GetDouble();
}

static class NumberGeneratorExtensionMethods
{
    public static double GetTheDouble(this INumberGenerator input)
    {
        return input.GetDouble();
    }

    public static decimal GetTheDoubleCastToDecimal(this INumberGenerator input)
    {
        return (decimal) input.GetDouble();
    }
}

class MockExample
{
    public void TriggerTheError()
    {
        var stub = MockRepository.GenerateStub<INumberGenerator>();

        // This works
        stub.Stub(obj => obj.GetTheDouble()).Return(1.2d);

        // This throws the error
        stub.Stub(obj => obj.GetTheDoubleCastToDecimal()).Return(1.2m);
    }
}

Here is the error:

System.InvalidOperationException : Type 'System.Decimal' doesn't match the return type 'System.Double' for method 'INumberGenerator.GetDouble();'

解决方案

Warning: this is really a suspicion more than anything else

The problem is that you're not really stubbing the extension methods at all - you're stubbing GetDouble in both cases.

I haven't looked at the code for Rhino Mocks for a while, but I suspect that the Stub method is basically saying:

  • Get ready for some calls on the mock!
  • Call the delegate passed in as an argument
  • Note which calls were made

That means you're effectively doing this:

canGetDecimal.Stub(ng => ng.GetDouble()).Return(1.2d);
canGetDecimal.Stub(ng => (decimal) ng.GetDouble()).Return(1.2m);

At that point, it would notice that you called GetDouble - but then you're trying to set the return value to 1.2m, which is invalid.

You could validate this pretty easily, with some logging. Add a log line to GetTheDoubleCastToDecimal and then split out the Stub call from the Return call:

Console.WriteLine("Before Stub");
var stubCall = canGetDecimal.Stub(obj => obj.GetTheDoubleCastToDecimal();
Console.WriteLine("After Stub");
stubCall.Return(1.2m);

I strongly suspect you'll find that whatever logging you add into the extension method is still logged between "Before Stub" and "After Stub" - showing that the extension method isn't being mocked out.

Moral: don't try to mock/stub extension methods. They're not polymorphic; they're just static methods, and it would be pretty tricky to fake them without deep wizardry. Only try to fake out genuinely polymorphic operations.

这篇关于打桩静态扩展方法似乎犀牛制品工作,除非我投返回变量。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆