为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Mockito.inOrder 验证按确切顺序调用模拟方法

使用 Mockito.inOrder 验证按确切顺序调用模拟方法

翻翻过去那场雪 2021-06-22 17:05:11
我正在尝试测试是否按预期顺序调用模拟对象上的方法。下面是一个简化的例子:@Testpublic 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 验证 method2 是否在method1之后的任何地方调用,但不是立即调用(即,在两者之间没有调用其他方法)。因为我要多次添加元素,所以这是很有可能的。这意味着,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 invocationsinOrder1.verifyNoMoreInteractions();
查看完整描述

2 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

这里没有答案:你走错了路(至少对于给定的例子):

意思是:当你创建一个“API”时,你要实现“易于使用,难以误用”。需要按特定顺序调用方法的 API 无法实现这一点。因此:感觉需要以编程方式检查订单可能表明您正在做“错误的事情”。您应该设计一个“做正确的事情”的 API,而不是期望您的代码的用户为您做这件事。

除此之外:当您正在测试列表,你绝对希望使用摆在首位嘲讽。

您想确保元素以特定顺序添加到列表中吗?然后一个简单的

assertThat(actualList, is(expectedList));

是您的测试应该检查的唯一一件事!

意思是:不是测试实现细节(add()使用这个和那个参数,按这个和那个顺序调用),你只需检查该操作的可观察结果。你不关心添加的顺序,也许重新设置和更新,你只关心最终的结果!

鉴于 OP 的评论:当您必须“按顺序”处理某些调用/对象时,您应该设计一个允许您传达该意图的界面。您只是通过单元测试来测试您的意图。这当然是一个好的开始,但还不够!

基本上,有两个概念可以为您工作:

  • 序号:当对象按顺序进入时,顺序很重要,那么每个对象都应该收到一个唯一的(最好是升序的)序号。然后每个处理元素的步骤都可以简单地记住最后处理的序列号,如果进入的是较低的序列号,则抛出异常。

  • “命令”的序列。OP 希望确保方法调用按顺序发生。这根本不是一个有用的抽象。相反:可以创建一个Command类(执行“某事”),然后为每个所需的活动创建不同的子类。然后您的处理器只需创建一个List<Command>. 现在测试归结为:生成这样一个序列,并检查每个条目是否属于给定类型。



查看完整回答
反对 回复 2021-06-30
  • 2 回答
  • 0 关注
  • 287 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信