使用 Moq 模拟受保护的泛型方法
在 Moq 中模拟受保护的虚拟(非通用)方法很容易:
public class MyClass
{
....
protected virtual int MyMethod(Data data){..}
}
并且模拟它:
myMock.Protected().Setup<int>("MyMethod", ItExpr.Is<Data>( ...
如果受保护的方法是通用的,我找不到使用相同技术的方法,例如:
protected virtual int MyMethod<T>(T data)
除了使用之外,任何想法如何做到这一点高度赞赏覆盖该方法的包装类。
To mock a protected virtual (non-generic) method in Moq is easy:
public class MyClass
{
....
protected virtual int MyMethod(Data data){..}
}
And to mock it:
myMock.Protected().Setup<int>("MyMethod", ItExpr.Is<Data>( ...
I could not find a way to use the same technique if the protected method is generic, like:
protected virtual int MyMethod<T>(T data)
Any idea how to do it, besides using a wrapper class to override that method, is highly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我检查了源代码,似乎不支持使用 Moq 模拟受保护的泛型方法:
Protected()
方法创建类ProtectedMock的实例;
它使用以下方法来获取您要模拟的方法:它使用 Type.GetMethod 来获取模拟方法,但是
GetMethod
(尽管 MSDN 的说法不同)不能很好地使用泛型,请参阅:通用方法的 GetMethod
获取通用方法而不使用 GetMethods
旁注:
在我看来,嘲笑受保护的成员是一种代码味道,我宁愿通过重构我的设计来尝试避免它(除了 Moq 中不支持它)。
I've checked the source and it seems mocking protected generic methods with Moq is not supported:
The
Protected()
method creates an instance of a classProtectedMock<T>
which uses the following method to get the method that you want to mock:It uses Type.GetMethod to get the method for mocking, but
GetMethod
(although MSDN states differently) don't play nice with generics, see:GetMethod for generic method
Get a generic method without using GetMethods
Side note:
In my opinion mocking a protected member is a code smell, and I would rather try to avoid it anyway with refactoring my design (beside that it's not supported in Moq).
自 Moq 4.13 (2019-09-01) 起,可以通过使用
As
来实现受保护的方法,使用It.IsAnyType
来实现泛型类型参数:classUnderTest.Protected( ).As().Setup(x =>; x.MyMethod(It.IsAny())).Returns(...);
并为模拟方法创建以下接口:
完整示例:
It can be done since Moq 4.13 (2019-09-01) by using
As
for protected methods andIt.IsAnyType
for generic type arguments:classUnderTest.Protected().As<IMyMethodMock>().Setup(x => x.MyMethod(It.IsAny<It.IsAnyType>())).Returns(...);
And create the following interface for the mocking method:
Full example: