【问题标题】:How to print all interactions with a mock using Mockito如何使用 Mockito 打印与模拟的所有交互
【发布时间】:2016-11-24 09:00:45
【问题描述】:

假设我必须在ClassA 上编写一些测试,其中有一个ClassB 作为成员,我在嘲笑ClassB

在测试结束时,我想使用verify(..)verifyNoMoreInteractions(..) 来设置所有模拟调用的行为和验证。

假设 mock 有超过 10 种不同方法的交互。

有没有办法让 JUnit 打印所有模拟交互,然后在代码中使用它?

现在我只是在阅读代码并查找调用,而不是在测试中编写验证行。我确信有一种更简单的方法(在我的情况下不可能使用 TDD :))

我的用例:我有一个带有算法的类,它使用了我模拟的许多其他类。在添加一个调用大量其他方法的新方法时,我想确保只有 x 个方法被调用 y 次,因为代码现在正在工作。这将确保如果将来有人更改某些内容,例如错误地调用方法 5 次而不是 4 次,那么测试将失败。

【问题讨论】:

  • 你的目标是什么?你试过什么?为什么需要打印这些交互,你将如何“在代码中使用它”?
  • @Onheiron 在获得所有与 mock 的交互后,我可以使用 verify(mock, ti​​mes(x)).method(1);在此之后 verifyNoMoreInteractions(mock) 我想拥有交互列表以设置方法的行为
  • 要使用verify(mock, times(x)).method(1);,您不需要所有交互的列表,这就是mockito 所做的:它检查与mock.method(1) 的交互是x 并且没有更多/更少。跨度>
  • @Onheiron 是的,我知道这个技巧,如果你有 7-10 个其他模拟类,每个模拟有 10-20 个交互,我希望提前获得交互列表,而不是写所有的验证,而不是写一个,运行,修复等等..
  • 预期的交互次数应该由您正在测试的行为给出。我的意思是,您不是从交互列表开始,然后编写验证(无论这意味着什么),而是从期望的行为(一组期望的交互)开始,然后检查这些行为。

标签: java junit mocking mockito


【解决方案1】:

您可以使用MockingDetailsprintInvocationsgetInvocations 来检查属于模拟的交互。但是,这不会按发生的顺序生成属于多个模拟的调用列表:只是与每个模拟的交互。

代码 sn-p,由 elhefeAnand Rockzz 贡献:

import static org.mockito.Mockito.mockingDetails;

System.out.println(mockingDetails(mock).printInvocations());
/* or */
System.out.println(mockingDetails(mock).getInvocations());

承认您在 cmets 中的不情愿和警告,我想说这是一种技术,它更多地锁定您当前的实现,而不是 分析您的实际约束并防止回归时间>。此外,如果您的算法与直接合作者有很多交互,这可能表明该算法应该被重构。

如果系统是未经测试或未记录的遗留代码,这可能是一种以编程方式生成回归测试或分析的实用方法——临时起点用于更明智的回归测试——但在相反,我会先记录每个组件的合同,然后编写一个测试来确认这些交互和约束。 Mockito 建议(通过 this article by Mockito's original developer 暗示)倾向于添加存根直到测试通过,并且仅在存在昂贵或非幂等副作用的情况下添加验证/计数。

【讨论】:

  • 因为我每次回到这条评论时都必须重新弄清楚这一点:import static org.mockito.Mockito.mockingDetails; System.out.println(mockingDetails(mock).printInvocations());
  • import static org.mockito.Mockito.mockingDetails; System.out.println(mockingDetails(mock).getInvocations());
猜你喜欢
  • 2019-11-07
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
相关资源
最近更新 更多