java - 使用 Mockito.inOrder 验证模拟方法是否按确切顺序调用
问题描述
我正在尝试测试是否按预期顺序调用模拟对象的方法。下面是简化的例子:
@Test
public void test() {
List<String> mockedList = Mockito.mock(List.class);
for (int i = 0; i < 5; i++) {
mockedList.add("a");
mockedList.add("b");
mockedList.add("c");
}
// I want only this to pass.
InOrder inOrder1 = Mockito.inOrder(mockedList);
inOrder1.verify(mockedList).add("a");
inOrder1.verify(mockedList).add("b");
inOrder1.verify(mockedList).add("c");
// I want this to fail.
InOrder inOrder2 = Mockito.inOrder(mockedList);
inOrder2.verify(mockedList).add("c");
inOrder2.verify(mockedList).add("b");
inOrder2.verify(mockedList).add("a");
}
尽管验证顺序 ( c -> b -> a
) 与调用顺序 ( a -> b -> c
) 不同,但此测试通过。这是因为 Mockito 验证方法 2 是否在方法 1 之后的任何地方调用,但不是立即调用(即,两者之间没有调用其他方法)。由于我多次添加元素,这很有可能。这意味着,Mockito InOrder 通过b -> a -> c -> a -> c -> b -> c -> b -> a ...
但我希望这失败,并确保订单始终a -> b -> c -> a -> b -> c -> a -> b -> c ...
更新:验证的正确方法是验证相同数量的迭代顺序(接受答案的摘要):
for (int i = 0; i < 5; i++) {
inOrder1.verify(mockedList).add("a");
inOrder1.verify(mockedList).add("b");
inOrder1.verify(mockedList).add("c");
}
// fail the test if we missed to verify any other invocations
inOrder1.verifyNoMoreInteractions();
解决方案
问题是你需要添加
inOrder.verifyNoMoreInteractions();
使用您的循环,您可以生成类似的调用
- 添加(一)
- 添加(b)
- 添加(c)
- 添加(一)
- 添加(b)
- 添加(c)
当你然后检查
inOrder.verify(mockedList).add("b");
inOrder.verify(mockedList).add("c");
inOrder.verify(mockedList).add("a");
它匹配调用 (add(b), add(c), add(a))。不检查其他呼叫。
- 添加(一)
- 添加(b)
- 添加(c)
- 添加(一)
- 添加(b)
- 添加(c)
所以我认为你必须选择:1)验证所有调用 a、b、c、a、b、c 2)验证你的模拟没有更多的交互发生
顺便说一句,如果您将验证更改为
inOrder.verify(mockedList).add("c");
inOrder.verify(mockedList).add("b");
inOrder.verify(mockedList).add("a");
它将失败,因为它与调用不匹配:-)