快速测试:规避依赖性

自动化测试是验证应用程序逻辑正确性的有用工具,也是防止错误的手段-软件在不断变化,测试是对潜在退化的早期警告。

但是,第三方代码在测试环境中并不总是能很好地发挥作用。

在这篇文章中,我们将研究一个障碍第三方代码的真实示例,以及如何解决它。

我们正在编写一个简单的类来记录“面包屑”(又名日志事件)。 我们会将这些事件记录到AWSKinesisFirehose中,并使用AWS为此提供的客户端。 这是未经测试的世界中此类的外观:

由于Swift是静态类型的,因此我们不能只传递任何类。 因此,我们可以使用一种称为IDEPEM的技术。

  • D倾向
  • 太好了
  • 协议
  • (E quatable
  • 模拟)

我们已经在注入我们的模拟类,以便涵盖IDEPID部分(这里不需要E quatable模拟)。

因此,接下来,使E成为协议。

诀窍是修改AWSFirehoseRecorder的类型,以便可以使用我们可以作为替代实例化的类型来对其进行描述。

在这种情况下,这意味着扩展AWSFirehoseRecorder,使其实现我们自己设计的协议。 该协议仅描述目标测试类使用的AWSFirehoseRecorder的方法:

扩展AWSFirehoseRecorder以在其类型描述中包括该协议。 它已经在其实现中实现了协议。

然后,我们创建自己的对象来满足该协议,并将其用作AWSFirehoseRecorder的代表

我们的假冒记录器现在实现了一个协议,而不是子类化第三方类型。

请注意,我们的模拟类不再引用或覆盖AWSFirehoseRecorder

现在我们的目标测试类仍将使用AWSFirehoseRecorder.default()作为默认参数,但否则将不知道什么是AWSFirehoseRecorder 。 相反,它将事件传递给BreadcrumbRecordable

注入依赖,一切都是协议

现在,我们可以将模拟作为测试中AWSFirehoseRecorder的替代者 。 我们可以撤回事件以验证事件是否到达,并且可以检查事件的正确性:

现在可以检查传递到记录器的数据

通过使用协议和一些Swift类型技巧,我们设法从测试图片中巧妙地剪裁了外部代码,从而甚至从未实例化它。 相反,我们清除了测试和验证我们自己的代码的路径,并使IDEPEM强大的功能处于休眠状态。