如何验证没有在对象的依赖项上调用方法?
例如:
public interface Dependency {
void someMethod();
}
public class Foo {
public bar(final Dependency d) {
...
}
}
使用 Foo 测试:
public class FooTest {
@Test
public void dependencyIsNotCalled() {
final Foo foo = new Foo(...);
final Dependency dependency = mock(Dependency.class);
foo.bar(dependency);
**// verify here that someMethod was not called??**
}
}
更有意义:
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
// ...
verify(dependency, never()).someMethod();
此功能的文档在 §4 "Verifying exact number of invocations / at least x / never",never
javadoc 是 here。
使用 Mockito.verify
方法的第二个参数,如下所示:
Mockito.verify(dependency, Mockito.times(0)).someMethod()
never()
的可读性并不比 times(0)
高很多。但是 never
的存在确实增加了认知负荷,使 mockito 系统更难理解和记住如何使用。所以真正的 mockito 不应该在他们的 API 中包含 never
,它不值得付出精神上的代价。
someMethod
被调用 0 次,还是仅验证 someMethod
从未使用零参数调用?
someMethod
被称为零次 - 未验证。
作为一种更通用的模式,我倾向于在测试中使用 @After
块:
@After
public void after() {
verifyNoMoreInteractions(<your mock1>, <your mock2>...);
}
然后测试可以自由地验证应该调用的内容。
此外,我发现我经常忘记检查“无交互”,后来才发现调用了不应该调用的东西。
所以我发现这种模式对于捕获所有未经过特别验证的意外调用很有用。
verifyNoMoreInteractions
的情况下进行验证?这里的其他答案依赖于测试作者明确记得列出这些检查:这在我的书中太容易出错了。
首先:您应该始终导入 mockito static,这样代码将更具可读性(和直观性):
import static org.mockito.Mockito.*;
实际上有很多方法可以实现这一点,但是(可以说)使用
verify(yourMock, times(0)).someMethod();
在您的测试中使用方法,当在其他测试中使用它来断言一定数量的执行时,如下所示:
verify(yourMock, times(5)).someMethod();
替代方案是:
verify(yourMock, never()).someMethod();
或者-当您真的想确保实际上根本没有调用某个模拟对象时-您可以使用:
verifyZeroInteractions(yourMock)
请注意:verifyZeroInteractions(Object... mocks) 已弃用。从 3.0.1 版开始。现在推荐的方法是:
verifyNoInteractions(yourMock)
verifyNoMoreInteractions()
和 verifyZeroInteractions()
方法在内部具有与以下相同的实现:
public static transient void verifyNoMoreInteractions(Object mocks[])
{
MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}
public static transient void verifyZeroInteractions(Object mocks[])
{
MOCKITO_CORE.verifyNoMoreInteractions(mocks);
}
所以我们可以在模拟对象或模拟对象数组上使用它们中的任何一个来检查是否没有使用模拟对象调用任何方法。
正如一个建议,如果您想在语法级别与 Behavior-driven development 样式更加一致,则有 BDDMockito:
你可以使用:
then(dependency).should(never()).someMethod();
作为等效替换:
verify(dependency, never()).someMethod();
never
是最好和最具体的方法,但如果您需要检查整个模拟对象,也可以考虑verifyZeroInteractions(mockObject)
或verifyNoMoreInteractions(mockObject)
。verifyZeroInteractions
已被弃用。verifyNoInteractions
是建议的替代方案。发表此评论时的 Mockito 版本是 3.3.3