是否可以使用Rhino.Mocks模拟静态方法? 如果Rhino不支持这个,是否有一种模式或某种东西可以让我做到这一点?
答案 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)可以被模拟。显然,静态成员不是继承的,因此存在问题。