C# 使用 Rhino.Mocks 模拟静态方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/540239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mocking Static methods using Rhino.Mocks
提问by abhilash
Is it possible to mock a static method using Rhino.Mocks? If Rhino does not support this, is there a pattern or something which would let me accomplish the same?
是否可以使用 Rhino.Mocks 模拟静态方法?如果 Rhino 不支持这一点,是否有一种模式或什么可以让我完成同样的事情?
采纳答案by Judah Gabriel Himango
Is it possible to mock a static method using Rhino.Mocks
是否可以使用 Rhino.Mocks 模拟静态方法
No, it is not possible.
不,这是不可能的。
TypeMock can do this because it utilizes the CLR profiler to intercept and redirect calls.
TypeMock 可以做到这一点,因为它利用 CLR 分析器来拦截和重定向调用。
RhinoMocks, NMock, and Moq cannot do this because these libraries are simpler; they don't use the CLR profiler APIs. They are simpler in that they use proxies to intercept virtual members and interface calls. The downside of this simplicity is that they cannot mock certain things, such as static methods, static properties, sealed classes, or non-virtual instance methods.
RhinoMocks、NMock 和 Moq 无法做到这一点,因为这些库更简单;他们不使用 CLR 分析器 API。它们更简单,因为它们使用代理来拦截虚拟成员和接口调用。这种简单性的缺点是它们不能模拟某些东西,例如静态方法、静态属性、密封类或非虚拟实例方法。
回答by Rytmis
Wrap the static method call in a virtual instance method in another class, then mock that out.
将静态方法调用包装在另一个类的虚拟实例方法中,然后模拟它。
回答by Richard Banks
The only mock framework that I know of that supports mocking statics is TypeMock.
我所知道的唯一支持模拟静态的模拟框架是 TypeMock。
As Rytmis suggested, you need to wrap the statics in something (i.e. an instance class with virtual methods or an interface) that you can then mock out.
正如 Rytmis 建议的那样,您需要将静态包装在一些东西中(即具有虚拟方法或接口的实例类),然后您可以模拟出来。
回答by vijaysylvester
I have been mocking using moq, I don't think we can mock static members using this because moQ creates a new proxy for the target (class or interface). So only the inheritable members (virtual in case of class, public in terms of interface ) can be mocked. Clearly, static members are not inherited, hence the problem.
我一直在使用 moq 进行模拟,我认为我们不能使用它来模拟静态成员,因为 moQ 为目标(类或接口)创建了一个新代理。所以只有可继承的成员(在类的情况下是虚拟的,在接口方面是公共的)可以被模拟。显然,静态成员不是继承的,因此存在问题。
回答by Vaccano
This is the biggest drawback to Rhino Mocks. I don't know that it is even possible for Rhino Mocks to have this implemented without a re-concept of how it does its mocking.
这是 Rhino Mocks 的最大缺点。我不知道 Rhino Mocks 甚至有可能在没有重新定义它如何进行模拟的情况下实现这一点。
回答by Steve Guidi
If you can't use TypeMock to intercept the method call, the recommended pattern to use is to create a proxy that forwards to the non-virtual or static methods you are interested in testing, then set the expectation on the proxy. To illustrate, consider the following classes.
如果您不能使用 TypeMock 来拦截方法调用,推荐使用的模式是创建一个代理,转发到您有兴趣测试的非虚拟或静态方法,然后在代理上设置期望。为了说明,请考虑以下类。
class TypeToTest
{
public void Method() { }
}
interface ITypeToTest
{
void Method();
}
class TypeToTestProxy : ITypeToTest
{
TypeToTest m_type = new TypeToTest();
public void Method() { m_type.Method(); }
}
By creating this proxy, you can now use an ITypeToTest
in place of where you were passing or setting a TypeToTest
instance, making sure that the default implementation uses the TypeToTestProxy
as it forwards to the real implementation. Then, you can create a mock ITypeToTest
in your test code and set expectations accordingly.
通过创建此代理,您现在可以使用ITypeToTest
代替 传递或设置TypeToTest
实例的位置,确保默认实现在TypeToTestProxy
转发到实际实现时使用 。然后,您可以ITypeToTest
在测试代码中创建一个模拟并相应地设置期望值。
Note that creating these proxies can be very tedious, error-prone, and time consuming. To address this I maintain a library and set of tools that generate assemblies containing these types for you. Please refer to this pagefor more information.
请注意,创建这些代理可能非常乏味、容易出错且耗时。为了解决这个问题,我维护了一个库和一组工具,为您生成包含这些类型的程序集。请参阅此页面了解更多信息。