何时使用 Mockito.verify()?
我为 3 个目的编写 jUnit 测试用例:
I write jUnit test cases for 3 purposes:
- 为了确保我的代码在所有(或大部分)输入组合/值下满足所有必需的功能.
- 为了确保我可以更改实现,并依靠 JUnit 测试用例告诉我我的所有功能仍然得到满足.
- 作为我的代码处理的所有用例的文档,并充当重构规范 - 如果代码需要重写.(重构代码,如果我的 jUnit 测试失败 - 你可能错过了一些用例).
我不明白为什么或何时应该使用 Mockito.verify()
.当我看到 verify()
被调用时,它告诉我我的 jUnit 正在意识到该实现.(因此更改我的实现会破坏我的 jUnit,即使我的功能不受影响).
I do not understand why or when Mockito.verify()
should be used. When I see verify()
being called, it is telling me that my jUnit is becoming aware of the implementation. (Thus changing my implementation would break my jUnits, even though my functionality was unaffected).
我正在寻找:
正确使用
Mockito.verify()
的指南应该是什么?
jUnits 了解或紧密耦合到被测类的实现是否从根本上正确?
Is it fundamentally correct for jUnits to be aware of, or tightly coupled to, the implementation of the class under test?
推荐答案
如果类 A 的契约包括它调用 C 类型对象的方法 B 的事实,那么您应该通过制作 C 类型的模拟来测试这一点,并验证方法 B 是否已被调用.
If the contract of class A includes the fact that it calls method B of an object of type C, then you should test this by making a mock of type C, and verifying that method B has been called.
这意味着类 A 的契约有足够的细节来讨论类型 C(可能是接口或类).所以是的,我们谈论的规范级别不仅仅是系统要求",而是在某种程度上描述了实现.
This implies that the contract of class A has sufficient detail that it talks about type C (which might be an interface or a class). So yes, we're talking about a level of specification that goes beyond just "system requirements", and goes some way to describing implementation.
这对于单元测试是正常的.当您进行单元测试时,您希望确保每个单元都在做正确的事情",这通常包括它与其他单元的交互.这里的单元"可能是指类或应用程序的更大子集.
This is normal for unit tests. When you are unit testing, you want to ensure that each unit is doing the "right thing", and that will usually include its interactions with other units. "Units" here might mean classes, or larger subsets of your application.
更新:
我觉得这不仅适用于验证,也适用于存根.一旦您存根协作者类的方法,您的单元测试就在某种意义上变得依赖于实现.这有点像单元测试的性质.由于 Mockito 与验证一样重要,因此您使用 Mockito 的事实意味着您将遇到这种依赖关系.
I feel that this doesn't apply just to verification, but to stubbing as well. As soon as you stub a method of a collaborator class, your unit test has become, in some sense, dependent on implementation. It's kind of in the nature of unit tests to be so. Since Mockito is as much about stubbing as it is about verification, the fact that you're using Mockito at all implies that you're going to run across this kind of dependency.
根据我的经验,如果我改变一个类的实现,我经常不得不改变它的单元测试的实现来匹配.不过,通常情况下,我不必更改类是的单元测试清单;当然,除非更改的原因是存在我之前未能测试的条件.
In my experience, if I change the implementation of a class, I often have to change the implementation of its unit tests to match. Typically, though, I won't have to change the inventory of what unit tests there are for the class; unless of course, the reason for the change was the existence of a condition that I failed to test earlier.
这就是单元测试的意义所在.不受这种对协作者类使用方式的依赖影响的测试实际上是子系统测试或集成测试.当然,这些也经常使用 JUnit 编写,并且经常涉及到 mocking 的使用.在我看来,JUnit"是一个糟糕的名字,因为它可以让我们进行所有不同类型的测试.
So this is what unit tests are about. A test that doesn't suffer from this kind of dependency on the way collaborator classes are used is really a sub-system test or an integration test. Of course, these are frequently written with JUnit too, and frequently involve the use of mocking. In my opinion, "JUnit" is a terrible name, for a product that lets us produce all different types of test.
相关文章