46

是否可以使用 Rhino.Mocks 模拟静态方法?如果 Rhino 不支持这一点,是否有模式或其他东西可以让我完成同样的事情?

4

6 回答 6

72

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

不,这是不可能的。

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

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

于 2009-05-04T14:30:07.920 回答
22

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

于 2009-02-12T06:10:06.047 回答
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(); }
}

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

请注意,创建这些代理可能非常乏味、容易出错且耗时。为了解决这个问题,我维护了一个库和一组工具,为您生成包含这些类型的程序集。请参阅此页面了解更多信息。

于 2009-12-24T21:14:28.793 回答
4

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

正如 Rytmis 建议的那样,您需要将静态数据包装在可以模拟的东西(即具有虚拟方法或接口的实例类)中。

于 2009-02-12T22:42:02.073 回答
4

这是 Rhino Mocks 最大的缺点。我不知道 Rhino Mocks 甚至有可能在没有重新概念它如何进行模拟的情况下实现这个。

于 2009-11-05T03:59:09.120 回答
2

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

于 2009-08-21T10:37:38.337 回答