模拟任何给定类型参数的泛型方法调用
我有一个接口,
public interface IDataProvider
{
T GetDataDocument<T>(Guid document) where T:class, new()
}
我想以某种方式模拟它,它只会返回给定类型的新实例,而不管确切的类型如何,例如:(
myMock.Setup(m => m.GetDataDocument<It.IsAny<Type>()>(It.IsAny<Guid>()))
.Returns(() => new T());
这当然不起作用,因为我不能只是给起订量提供任何类型参数,我不知道必须返回哪种类型
对此有什么想法吗?
I have an interface
public interface IDataProvider
{
T GetDataDocument<T>(Guid document) where T:class, new()
}
I'd like to mock it in a way, that it would just return a new instance of a given type, regardless of the exact type, something like:
myMock.Setup(m => m.GetDataDocument<It.IsAny<Type>()>(It.IsAny<Guid>()))
.Returns(() => new T());
(which doesn't work of course, because I cannot just give any type parameter to moq, and I can't know which type must be returned.
Any ideas on this one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
除了使用模拟之外,也许您的情况最好使用 存根。
如果您确实需要模拟(以便您可以验证是否调用了
GetDataDocument
)。有时,直接创建一个 Mock 类会更容易,而不是尝试使用 Mocking 框架。与您的测试相比:
Instead of using a mock, maybe your case would be better to use a Stub.
If you truly need a mock (so you can verify that
GetDataDocument
was called). Instead of trying to wrestle with a Mocking framework it sometimes is easier to just create a Mock class out right.And than in your test:
使用 Moq 4.13 或更高版本,您可以使用
It.IsAnyType
— 匹配任何类型It.IsSubtype
— 匹配 T 和 T 的正确子类型It.IsValueType< /code> — 只匹配值类型
要获取泛型参数的值或使用原始方法执行其他操作,您可以使用
InvocableAction
或的
IInitation
参数>InvocableFuncsetup.Callback(new InvocableAction(invocation => ...))
setup.Returns(new InvocableFunc(invocation => ...))
代码>这是一个例子:
With Moq 4.13 or later you can use
It.IsAnyType
— matches any typeIt.IsSubtype<T>
— matches T and proper subtypes of TIt.IsValueType
— matches only value typesTo get the value of the generic argument or do some other operation with the original method, you can use
IInvocation
parameter ofInvocationAction
orInvocationFunc
setup.Callback(new InvocationAction(invocation => ...))
setup.Returns(new InvocationFunc(invocation => ...))
Here is an example:
对于您要使用此模拟进行的特定测试,您可能知道 T 是什么,对吧?
只需为此设置模拟:
无论如何,实际上并不建议重用模拟,因此请继续为手头的实际测试设置模拟。
For the particular test you are going to use this mock for, you probably know what T will be, right?
simply just setup the mock for that:
It's not really recommended to reuse the mocks anyway, so go ahead and setup mocks for the actual test at hand.
我遇到了类似的问题,我选择在这种情况下不使用存根,因为我不希望对正在测试的接口进行添加,从而需要立即更改测试代码。即添加新方法不应破坏我现有的测试。
为了让模拟工作,我在运行时在给定的程序集中添加了所有公共类型。
I had a similar issue, I chose against using a stub in this situation as I did not want additions to the interface being tested to require immediate changes to the test code. i.e. adding a new method should not break my existing tests.
To get the mock working I added all the public type in a given assembly at runtime.