java - Mockito 验证对模拟对象的最后一次调用

标签 java mockito call verify

我有一些逻辑需要测试,例如:

{
    ...
    A.add("1");
    ...
    A.add("what ever");
    ...
    A.add("2");
    A.delete("5");
    ...
}

我已经在测试中模拟了 A,我可以测试 add 方法在参数(“2”)上调用一次,例如:

Mockito.verify(mockedA).add("2");

我的问题是如何测试是否可以验证对方法 add 的最后一次调用是 add("2") 而不是其他参数。

因为上面的测试无法捕获是否有人意外添加另一个调用,例如最后的 add("3") 。请注意,之后我们不再关心 A 上的其他方法调用。我们也不关心方法被调用的次数、方法调用的顺序。 这里的关键点是我们是否可以验证某个mockedObject的某个方法的最后一个真实参数。

如果你问为什么需要这样的功能,我会说在现实世界中我们可能需要处理一些设置某些内容并且最后一组获胜的逻辑,并且为了避免有人意外设置其他一些意想不到的东西,我想用我们的 UT 来捕捉这个。而且为了不让测试变得过于复杂和简洁,所以我只希望验证对象的某个方法的最后一次调用,而不是验证诸如 order/noMoreInteractions/AtMostTimes 之类的东西。

最佳答案

关于调用顺序

默认情况下,Mockito.verify() 与调用顺序无关。
为了考虑到这一点,请将模拟包装在 InOrder 实例中,并在此实例上执行调用验证。

关于不再进行交互

如果在您想要验证的方法之后不再调用模拟,您可以使用 Mockito.verifyNoMoreInteractions(Object...mocks) 检查给定的模拟是否有任何未经验证的交互例如:

InOrder inOrder = Mockito.inOrder(mockedA);
inOrder.verify(mockedA).add("1");
inOrder.verify(mockedA).add("2");
Mockito.verifyNoMoreInteractions(mockedA);
<小时/>

如果在您想要验证的方法之后仍可能调用模拟,您可以在验证调用后通过传递 VerificationMode 添加对 verify(T mock, VerificationMode mode) 的调用 检查是否最多执行了 2 次调用。

InOrder inOrder = Mockito.inOrder(mockedA);
inOrder.verify(mockedA).add("1");
inOrder.verify(mockedA).add("2");
Mockito.verify(mockedA, Mockito.atMost(2)).add(Mockito.anyString());
<小时/>

关于你的想法和这种 mock 方式的警告

Since the test above can't catch if somebody by accident adds another call such as add("3") in the last.

Mockito 提供了一个强大而广泛的工具包来处理模拟。某些功能(例如验证)以及更具体的验证是否未检测到有关模拟或模拟的特定方法的更多交互使您的测试更难以阅读和维护
此外,当前您想要检查模拟上的调用是否按特定顺序执行。但您通常只想根据业务/逻辑场景的需要使用这些检查,而不是技术调用。
例如,假设在测试方法中,由于业务原因,模拟方法被调用 3 次,而模拟方法被调用 2 次。在有两次预期调用的情况下,检查它是否仅被调用两次而不是更多次是有意义的。
但一般来说,您应该小心,单元测试不要过度使用模拟验证,这可能看起来像是对流程描述的断言,而不是对行为/逻辑的断言。

关于java - Mockito 验证对模拟对象的最后一次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50503729/

相关文章:

java - 无法在 Glassfish 中获取 Oracle 连接

ruby - 如何知道调用了哪个模块用户

PHP- Zend Framework- 在 CentOS 服务器上从另一个 Action 的 View 调用 Action

java - 如何为向上、向下、向左、向右箭头向 JTextField 添加监听器?

java - 我如何知道 Java 19 结构化并发 StructuredTaskScope 是否关闭(取消)?

Java递归斐波那契数列

Java - 使用 SOAPMessage 请求模拟 SOAP 调用

java - PowerMockito : Test is constructing real object instead of mock in spite of whenNew

java - 如何将模拟对象注入(inject)另一个已经模拟的对象

java - 从 Android 中的非 Activity 类调用方法