java - Mockito:InOrder.verify 不禁止模拟上的中间调用

标签 java unit-testing mockito

我想测试模拟上的方法是否以正确的顺序、正确的参数以及与相应参数相关的正确的方法调用数量进行调用。

假设我想测试 List.add 被调用,如下所示:

List<String> listMock = Mockito.mock(List.class);
listMock.add("A");
listMock.add("C");

InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

这个测试工作正常,但对于我的意图来说还不够严格。问题是,如果实际调用发生变化,测试不一定会失败。例如,如果您执行类似的操作:

List<String> listMock = Mockito.mock(List.class);
listMock.add("A");
listMock.add("B");
listMock.add("C");

// this won't fail
InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

我确实想验证是否首先使用“A”调用 add,然后使用“C”调用 add。同时 add 根本不应该用任何东西来调用。

我想出的唯一解决方案是 Mockito.verify 和 InOrder.verify 的组合:

// this works but doesn't seem very elegant
Mockito.verify(listMock, times(2)).add(Mockito.anyString());
InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
inOrder.verifyNoMoreInteractions();

现在我的测试逻辑分布在 Mockito.verify 和 InOrder.verify 中。

是否有更优雅的解决方案来禁止中间调用add

最佳答案

您应该对模拟对象调用 verifyNoMoreInteractions() 方法以确保不再进行调用:

InOrder inOrder = Mockito.inOrder(listMock);
inOrder.verify(listMock).add("A");
inOrder.verify(listMock).add("C");
Mockito.verifyNoMoreInteractions(listMock);

这样,如果中间发生另一个调用,验证就会失败,因为它预计有 2 次调用,而您的示例调用了 3 次。它还确保完全按照所需的顺序调用给定的参数。

关于java - Mockito:InOrder.verify 不禁止模拟上的中间调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55357899/

相关文章:

Java Swing 图形用户界面。在按住鼠标按钮的同时激活/触发更多按钮

java - 给定链表的成对交换元素(Java解决方案)

.net - SQLite 程序集未复制到输出文件夹以进行单元测试

java - 是否可以使用 Mockito 验证测试的对象方法调用?

java - 模拟AmazonS3Client,而无需任何依赖,如s3mock或s3ninja

java - serversocket.accept()何时会引发异常? [java]

java - Android Studio 套接字问题。无法解析 libcore.util.Objects

java - 为什么使用 JUnit 编写测试类时不需要扩展 TestCase?

ios - Xcode 单元测试缺少某些项目类

android - 当进行 retrofit2 请求时,单元测试 Call 对象为 null