如何使用Rhino Mock模拟扩展方法?

9
我已经通过一些扩展方法扩展了IDataReader类型的对象。问题是,现在当我尝试模拟IDataReader时,扩展方法不包括在模拟中,因此当行Expect.Call(reader.ExtensionMethod()).Return(someValue)被执行时,将执行ExtensionMethod,这不是我想要的!我希望该调用被记录,并且当从其他地方调用扩展方法时,它返回someValue

有人知道如何解决这个问题吗?


2
可能是重复的问题:如何使用Moq模拟扩展方法? - abatishchev
1
@abatishchev:我会说是和否的:)。你提出的话题并没有回答RhinoMock是否可能,而且我们还有时间因素...在过去的18个月中,有人可能已经找到了一个聪明的解决方案。 - Tomas Jansson
4个回答

15

声明:我为Telerik工作。

扩展方法实际上是隐藏成实例方法的静态方法。RhinoMock无法模拟静态方法,除非使用另一个使用分析器的模拟库。

这样的库是由Telerik推出的JustMock


好的...那么这怎么帮助我解决RhinoMock的问题呢? - Tomas Jansson
2
不行的:) 很抱歉,RhinoMock无法实现这个功能。RhinoMock通过继承对象并重写方法来拦截对方法的调用(这就是为什么它们必须是虚拟的)。您无法覆盖静态(扩展)方法,这就是Rhino在此情况下失败的原因。 - Slavo
我目前知道有两个库可以做到这一点 - JustMock,我在回复中已经链接了它,以及TypeMock(http://www.typemock.com/)。它们都使用分析器并在较低级别上拦截方法调用,而不依赖于覆盖。这样做速度较慢,但可以完成工作。 - Slavo
1
Microsoft Fakes可以为扩展程序提供Shim。 - zaitsman
十一年后,这条评论仍然很有用。谢谢你,Slavo ;) - TPAKTOPA

2

目前看来答案是否定的。不过很遗憾,但我通过编写一个模拟类来解决我想要模拟的接口的问题。由于我并不需要那么多接口方法,所以进展得相当快。


6
那我不知道为什么你没接受Slavo的回答,因为他说的和我一样,而且他还是第一个回答的 :) - Ignacio Soler Garcia

0

可以在没有任何框架的情况下存根扩展方法或任何其他静态方法。以下代码允许您这样做,您只需要存根_doSumm

public static class MyExtensions
{
    public static Func<int,int, int> _doSumm = (x, y) => x + y;

    public static int Summ(this int x, int y)
    {
        return _doSumm(x, y);
    }
}

0
在我的实例中,我将需要存根的扩展方法包装成帮助类的方法,并在新接口中公开包装器方法。我将生产代码切换为注入此帮助程序类的实例,并更改代码以调用新方法。单元测试正在注入一个方便地制作的帮助程序接口存根。
虽然这个解决方案并不完美,但仍然比交换模拟框架要少得多。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接