使用Rhino.Mocks模拟静态方法

时间:2009-02-12 06:07:48

标签: c# tdd mocking rhino-mocks

是否可以使用Rhino.Mocks模拟静态方法? 如果Rhino不支持这个,是否有一种模式或某种东西可以让我做到这一点?

6 个答案:

答案 0 :(得分:71)

  

是否可以模拟静态方法   使用Rhino.Mocks

不,这是不可能的。

TypeMock可以这样做,因为它利用CLR分析器来拦截和重定向调用。

RhinoMocks,NMock和Moq无法做到这一点,因为这些库更简单;他们不使用CLR分析器API。它们更简单,因为它们使用代理来拦截虚拟成员和接口调用。这种简单性的缺点是它们无法模拟某些事物,例如静态方法,静态属性,密封类或非虚拟实例方法。

答案 1 :(得分:22)

将静态方法调用包装在另一个类的虚拟实例方法中,然后将其模拟出来。

答案 2 :(得分:17)

如果您无法使用TypeMock拦截方法调用,则建议使用的模式是创建一个代理,该代理转发到您感兴趣的非虚拟或静态方法,然后在代理上设置期望值。为了说明,请考虑以下类。

class TypeToTest
{
    public void Method() { }
}

interface ITypeToTest
{
    void Method();
}

class TypeToTestProxy : ITypeToTest
{
    TypeToTest m_type = new TypeToTest();

    public void Method() { m_type.Method(); }
}

通过创建此代理,您现在可以使用ITypeToTest代替传递的位置或设置TypeToTest实例,确保默认实现使用TypeToTestProxy作为它转发真正的实施。然后,您可以在测试代码中创建模拟ITypeToTest并相应地设置期望。

请注意,创建这些代理可能非常繁琐,容易出错且耗时。为了解决这个问题,我维护了一个库和一组工具,可以为您生成包含这些类型的程序集。有关详细信息,请参阅this page

答案 3 :(得分:4)

我所知道的唯一支持模拟静态的模拟框架是TypeMock。

正如Rytmis建议的那样,你需要将静态包装在一些东西中(即一个带有虚方法或接口的实例类)然后你可以模拟出来。

答案 4 :(得分:4)

这是Rhino Mocks的最大缺点。我不知道Rhino Mocks甚至可以实现这一点而不重新考虑它是如何进行模拟的。

答案 5 :(得分:2)

我一直在使用moq进行模拟,我认为我们不能使用这个来模拟静态成员,因为moQ为目标(类或接口)创建了一个新的代理。因此,只有可继承的成员(在类的情况下为虚拟,在接口方面为public)可以被模拟。显然,静态成员不是继承的,因此存在问题。