2012-04-12 203 views
30

如何模拟集成测试所需的许多依赖关系?嘲笑集成测试

我使用Mockito进行“纯粹”单元测试。在这种情况下,“纯粹”意味着测试一个类,嘲笑它的所有依赖。美丽。

现在来集成测试。让我们在这种情况下说的集成测试将测试是这样的:

  1. 消息放在一个队列
  2. 消息是“处理”
  3. 响应消息放在响应队列

我们还要说,步骤2中发生的处理是严重的事情。它依赖于大量的数据库交互,在多个外部服务,文件系统,各种事物上。流量也会触发很多副作用,所以我不能简单地确保响应是正确的 - 我需要验证副作用。

这些依赖关系中的每一个都由一个无状态的服务类包装,这使得它们很好,可以嘲弄。

人们如何处理?

我很乐意使用Mockito,以便我可以验证上述流程的副作用。然而,Mocktio的文档(在很大程度上是它的实现)似乎强烈反对在“纯粹”单元测试以外的环境中使用它。我试图走这条路线,但

  • 这是很难填充存根数据(有很多很多的)
  • 这是很难有春天注入的存根情况下进入我的豆子
  • 很困难重置'模拟,以便我可以验证一组不同的交互而不清除存根。

编辑

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

Whatdaya呢?

+1

只是为了澄清,因为集成测试可以采取两种方式。这听起来像是你的意思是集成测试,测试连接组件可以很好地协同工作(主要是测试API)。但是,有时整合是指端到端,所以你不会嘲笑你的服务,并且实际上允许它访问数据库。这个澄清可以帮助答案..请参阅http://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test为进一步澄清的类型 – 2012-04-12 21:06:57

+0

它确实适用于需要大量外部依赖性的任何测试(集成或端到端)。例如,我可以用HSQLDB实例替换我的数据库存根,但我仍然拥有所有其他服务。将编辑的问题稍微澄清.. – 2012-04-13 01:06:47

+0

那么你最终如何解决嘲讽问题? – Pupsik 2015-05-19 14:34:25

回答

7

伟大的问题。

看起来好像你碰到了Mockito的极限。如果你想检查对象交互,Mockito非常棒。

尽管如此,你想要的是在更高抽象层次上的可观察性(和可控性)。恐怕您需要的嘲笑或存根应该经过精心设计和手工制作。

在单元级别,这些模拟可以通过Mockito很好地生成。在集成层面,这变得更加困难,并且您将需要特制的可测​​试性接口。

+1

是的,听起来像是在集成层面上人们“尽力而为”,或者是通过嘲笑库或者通过实际访问服务/数据库的测试实例。我目前正在研究基于Groovy的Mockito扩展,以帮助集成测试减轻一点痛苦。 – 2012-04-16 01:07:10

7

为了模拟数据库,Web服务,文件系统等事情,您可能需要重构一些内容。对于每个外部服务,您应该编写一个包装类,该类包含您希望执行的每个操作的方法。每个这样的方法都不应该有实际的逻辑,而只需要以外部服务理解的方式传递参数,然后返回一个包含外部服务返回的任何数据的对象。例如,如果您正在与数据库交互,包装类可能会将其参数格式化为SQL语句,将其提交到现有的Connection对象中,并返回List作为结果。因为包装类的方法不包含任何逻辑(也就是说,没有if/else,没有循环,也没有异常处理)。没有必要单元测试包装类。您应该集成测试包装类,以确保其职责正确执行(例如,SQL语句对数据库具有预期的效果)。

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

+0

谢谢大卫。我的外部服务很好地抽象出来 - 每个服务都被一个Spring单例服务类包装。即使如此,对于复杂的场景,嘲笑也变得困难。有很多数据需要被扼杀,通常相同的服务方法会被多次调用,这意味着我需要让这些存根返回多个值,然后存在让这些注入Spring的问题..变得毛茸茸的。我必须假设人们以更简洁的方式解决了这个问题 – 2012-04-13 12:31:27

+0

他们是否必须用单身包装?单身人士是非常难以嘲笑的。你能设计一些东西,使包装不是单身? – 2012-04-13 12:38:35

+0

另外,我会询问为什么同一个服务方法在一次测试中被多次调用。也许你的测试方法太大?我坚信“每个测试方法的一个断言”规则;它确实为更清洁的测试做出了贡献。 – 2012-04-13 12:43:57

0

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

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