使用 Moq 模拟基类方法调用
我正在修改一个类方法,该方法格式化一些输入参数日期,这些日期随后在基类(位于另一个程序集中)的方法调用中用作参数。
我想验证传递给我的方法的日期在传递给基类方法时格式是否正确,因此我想最小起订量基类方法调用。起订量可以吗?
I am modifiying a class method which formats some input paramater dates which are subsequently used as params in a method call into the base class (which lives in another assembly).
I want to verify that the dates i pass in to my method are in the correct format when they are passed to the base class method so i would like to Moq the base class method call. Is this possible with Moq?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
截至 2013 年,您可以使用最新的起订量。这是一个示例
As of 2013 with latest Moq you can. Here is an example
如果我正确理解你的问题,你有一个在其他程序集中定义的类 A,然后类 B 或多或少地实现如下:
现在你想验证是否调用了 base.MyMethod ?
我不明白如何使用动态模拟库来做到这一点。所有动态模拟库(TypeMock 除外)都通过动态发出从相关类型派生的类来工作。
就您而言,您不能很好地要求 Moq 从 A 派生,因为您想测试 B。
这意味着您必须要求 Moq 给您一个
Mock
。然而,这意味着发出的类型派生自 B,虽然它可以重写 MyMethod(仍然是虚拟的)并调用其基类 (B.MyMethod),但它无法获取原始类并验证 B 是否调用 <代码>base.MyMethod。想象一下,您必须编写一个从 B 派生的类 (C)。虽然您可以重写 MyMethod,但您无法验证 B 是否调用 A:
同样,除了 TypeMock 可能的例外之外,动态模拟库无法执行您无法执行的任何操作手动做。
但是,我假设调用您尝试验证的基本方法会产生一些可观察到的副作用,因此如果可能,您可以使用基于状态的测试而不是基于行为的测试来验证调用该方法的结果吗?
无论如何,在大多数情况下,基于状态的测试应该是您的默认方法。
If I understand your question correctly, you have a class A defined in some other assembly, and then an class B implemented more or less like this:
And now you want to verify that base.MyMethod is called?
I don't see how you can do this with a dynamic mock library. All dynamic mock libraries (with the exception of TypeMock) work by dynamically emitting classes that derive from the type in question.
In your case, you can't very well ask Moq to derive from A, since you want to test B.
This means that you must ask Moq to give you a
Mock<B>
. However, this means that the emitted type derives from B, and while it can override MyMethod (which is still virtual) and call its base (B.MyMethod), it has no way of getting to the original class and verify that B callsbase.MyMethod
.Imagine that you have to write a class (C) that derives from B. While you can override MyMethod, there's no way you can verify that B calls A:
Again with the possible exception of TypeMock, dynamic mock libraries cannot do anything that you cannot do manually.
However, I would assume that calling the base method you are trying to verify has some observable side effect, so if possible, can you use state-based testing instead of behaviour-based testing to verify the outcome of calling the method?
In any case, state-based testing ought to be your default approach in most cases.
同意马克的观点,使用起订量是不可能的。
根据您的情况,您可以考虑从继承切换到组合。然后您将能够模拟依赖关系并验证您的方法。当然,在某些情况下,这可能不值得。
Agree with Mark, it's not possible using Moq.
Depending on your situation you may consider swithcing from inheritance to composition. Then you'll be able to mock the dependency and verify your method. Of course in some cases it just might not worth it.
将基类方法包装在一个方法中并设置该方法
例如
,现在设置 BaseMyMethod
wrap the base class method in a method and setup that method
e.g.
and now Setup the BaseMyMethod
这很可能是模拟基类。但你必须修改目标类。
对于前。 DerivedClass 扩展BaseClass。
BaseClass 具有方法 MethodA()、MethodB()、MethodC()...
DerivedClass 有这个方法:
您想要模拟基类以验证所有 MethodA()、MethodB()、MethodC()在MyMethod()内部被调用。
您必须在 DerivedClass 中创建一个字段:
并且还必须修改 MyMethod():
还要添加一个方法,该方法可以注入 this.self带有 Mock 对象的 字段
现在您可以模拟:
使用此技术,您还可以模拟嵌套方法调用。
It is quite possible mocking base class. But you will have to modify target class.
For ex. DerivedClass extends BaseClass.
BaseClass has methods MethodA(), MethodB(), MethodC()...
The DerivedClass has this method:
You want to mock base class in order to validate that all MethodA(), MethodB(), MethodC() are being called inside MyMethod().
You have to create a field in the DerivedClass:
And also You have to modify the MyMethod():
Also add a method, which can inject the this.self field with Mock object
Now you can mock:
Using this technic, you can also mock nested method calls.
我找到了这个解决方案 - 丑陋但它可以工作。
I found this solution - ugly but it could work.