使用 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 验证 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 invocations

inOrder1.verifyNoMoreInteractions();


翻翻过去那场雪
浏览 288回答 2
2回答

翻过高山走不出你

这里没有答案:你走错了路(至少对于给定的例子):意思是:当你创建一个“API”时,你要实现“易于使用,难以误用”。需要按特定顺序调用方法的 API 无法实现这一点。因此:感觉需要以编程方式检查订单可能表明您正在做“错误的事情”。您应该设计一个“做正确的事情”的 API,而不是期望您的代码的用户为您做这件事。除此之外:当您正在测试列表,你绝对不希望使用摆在首位嘲讽。您想确保元素以特定顺序添加到列表中吗?然后一个简单的assertThat(actualList,&nbsp;is(expectedList));是您的测试应该检查的唯一一件事!意思是:不是测试实现细节(add()使用这个和那个参数,按这个和那个顺序调用),你只需检查该操作的可观察结果。你不关心添加的顺序,也许重新设置和更新,你只关心最终的结果!鉴于 OP 的评论:当您必须“按顺序”处理某些调用/对象时,您应该设计一个允许您传达该意图的界面。您只是通过单元测试来测试您的意图。这当然是一个好的开始,但还不够!基本上,有两个概念可以为您工作:序号:当对象按顺序进入时,顺序很重要,那么每个对象都应该收到一个唯一的(最好是升序的)序号。然后每个处理元素的步骤都可以简单地记住最后处理的序列号,如果进入的是较低的序列号,则抛出异常。“命令”的序列。OP 希望确保方法调用按顺序发生。这根本不是一个有用的抽象。相反:可以创建一个Command类(执行“某事”),然后为每个所需的活动创建不同的子类。然后您的处理器只需创建一个List<Command>.&nbsp;现在测试归结为:生成这样一个序列,并检查每个条目是否属于给定类型。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java