协慌网

登录 贡献 社区

模拟和存根之间有什么区别?

我已经阅读过各种关于模拟和测试中存根的文章,包括Martin Fowler 的 Mocks Are Not Stubs ,但仍然不明白其中的区别。

答案

前言

对象有几种定义,不是真实的。一般术语是测试双倍 。这个术语包括: 虚拟存根模拟

参考

根据Martin Fowler 的文章

  • 虚拟对象传递但从未实际使用过。通常它们仅用于填充参数列表。
  • 对象实际上有工作实现,但通常需要一些使它们不适合生产的快捷方式(内存数据库就是一个很好的例子)。
  • 存根提供了在测试期间进行的调用的固定答案,通常不会对测试中编程的任何内容做出任何响应。存根还可以记录有关呼叫的信息,例如记住它 '发送' 的消息的电子邮件网关存根,或者可能只记录它 '发送' 的消息。
  • 模拟是我们在这里所讨论的:预编程的对象具有预期,形成了预期接收的调用的规范。

样式

Mocks vs Stubs = 行为测试与状态测试

原理

根据每次测试只测试一件事的原则,在一次测试中可能有几个存根,但通常只有一个模拟。

生命周期

使用存根测试生命周期:

  1. 设置 - 准备正在测试的对象及其存根协作者。
  2. 练习 - 测试功能。
  3. 验证状态 - 使用断言检查对象的状态。
  4. 拆解 - 清理资源。

使用模拟测试生命周期:

  1. 设置数据 - 准备正在测试的对象。
  2. 设置期望 - 准备主要对象正在使用的模拟期望。
  3. 练习 - 测试功能。
  4. 验证期望 - 验证是否已在 mock 中调用了正确的方法。
  5. 验证状态 - 使用断言检查对象的状态。
  6. 拆解 - 清理资源。

摘要

模拟和存根测试都给出了问题的答案: 结果是什么?

使用模拟测试也对以下方面感兴趣: 结果如何实现?

存根

我相信最大的区别是你已经用预定的行为编写了一个存根。所以你会有一个实现依赖的类(最有可能的抽象类或接口),你为了测试目的而伪装,这些方法只是用 set 响应来删除。他们不会做任何花哨的事情,你会在测试之外编写它的存根代码。

嘲笑

模拟是你的测试的一部分,你必须设置你的期望。模拟不是以预定方式设置的,因此您可以在测试中使用代码。某种方式的模拟是在运行时确定的,因为设置期望的代码必须在它们执行任何操作之前运行。

模拟和存根之间的区别

用模拟编写的测试通常遵循initialize -> set expectations -> exercise -> verify模式到测试。虽然预先编写的存根将遵循initialize -> exercise -> verify

模拟与存根之间的相似性

两者的目的是消除测试类或函数的所有依赖关系,以便您的测试更加集中,更简单,他们试图证明。

存根是简单的假物体。它只是确保测试顺利进行。
模拟是更聪明的存根。您验证您的测试通过它。