嘲笑集成测试

时间:2012-04-12 20:58:11

标签: mocking integration-testing mockito

如何模拟集成测试所需的许多依赖项?

我使用Mockito进行'纯'单元测试。在这种情况下,'Pure'意味着测试单个类,模拟它的所有依赖项。美丽。

现在进行集成测试。让我们说在这种情况下,集成测试将测试这样的事情:

  1. 消息被放入队列
  2. 消息已“已处理”
  3. 响应消息放在响应队列中
  4. 我们还要说步骤2中发生的处理是严肃的事情。它依赖于大量的数据库交互,多个外部服务,文件系统,各种各样的东西。流会触发很多副作用,所以我不能简单地确保响应是正确的 - 我需要验证副作用。

    这些依赖项中的每一个都由一个无状态服务类包装,这使它们很好并且可以模拟。

    人们如何处理这个?

    我很想使用Mockito,以便我可以验证上述流程会产生的副作用。然而,Mocktio的文档(在很大程度上它的实现)似乎强烈反对在“纯”单元测试之外的上下文中使用它。我试过这条路,但是

    • 很难填充存根数据(因为它有很多)
    • 很难让Spring将这些存根实例注入我的bean
    • 很难“重置”模拟,以便我可以在不清除存根的情况下验证不同的交互集。

    修改

    我知道我可以像HSQLDB实例那样处理数据库问题,但仍然存在外部服务的问题。为了重复性,我不能依赖那些服务,处于我需要的状态,等等。我看到的唯一选择是嘲笑它们。

    Whatdaya做什么?

3 个答案:

答案 0 :(得分:9)

为了模拟数据库,Web服务,文件系统等等,你可能想要重构一下。对于每个外部服务,您应该编写一个包装类,该类包含您希望执行的每个操作的方法。每个这样的方法都应该没有实际的逻辑,只是以外部服务理解的方式传递其参数,并返回包含外部服务返回的任何数据的对象。例如,如果您正在与数据库交互,则包装类可能将其参数格式化为SQL语句,将它们提交到现有的Connection对象中,并为结果返回List

因为包装类的方法不包含逻辑(即没有if / else,没有循环,也没有异常处理);没有必要对包装类进行单元测试。您应该集成测试包装器类,以确保其职责正确执行(例如,SQL语句对数据库具有所需的效果)。

现在重新编写与外部服务交互的类,以便它们与包装类交互。然后很容易对它们进行单元测试 - 你只需要模拟包装类。

答案 1 :(得分:8)

很棒的问题。

好像你达到了Mockito的极限。如果你想检查对象的相互作用,Mockito是很棒的。

然而,你想要的是在更高抽象层次上的可观察性(和可控性)。我担心你需要的嘲讽或短裤应该经过精心设计和手工制作。

在单位级别,通过Mockito可以很好地生成这些模拟。在集成级别,这变得更加困难,您将需要专门的可测试性接口。

答案 2 :(得分:-1)

如果有一些http或rest模拟框架,使用它应该是好的。

可以记录,修改和重播所有复杂的依赖关系。