【发布时间】:2011-10-12 02:12:45
【问题描述】:
关于 stub 与 mock 的文章很多,但我看不出 fake 和 stub 之间的真正区别。有人能说明一下吗?
【问题讨论】:
标签: testing terminology stub
关于 stub 与 mock 的文章很多,但我看不出 fake 和 stub 之间的真正区别。有人能说明一下吗?
【问题讨论】:
标签: testing terminology stub
我假设您指的是 Meszaros 介绍的术语。 Martin Fowler 也经常mentions them。我认为他在那篇文章中很好地解释了差异。
不过,我会用我自己的话再试一次:)
Fake 比 stub 更接近真实世界的实现。存根包含对预期请求的基本硬编码响应;它们通常用于单元测试,但它们无法处理预编程以外的输入。
Fakes 有更真实的实现,例如可以保留的某种状态。它们可用于系统测试以及单元测试目的,但由于某些限制或质量要求,它们不适合生产使用。
【讨论】:
fake 与它所替代的东西具有相同的行为。
存根具有一组“固定”的“预设”响应,这些响应特定于您的测试。
mock 对所拨打的电话有一系列期望。如果不满足这些期望,则测试失败。
所有这些都是相似的,因为它们取代了被测代码使用的生产协作者。
【讨论】:
【讨论】:
套用 Roy Osherove 在他的著作《单元测试的艺术》(第二版)中的话:
赝品是模仿其他物体的任何物体。赝品可以使用作为存根或模拟。
存根是一个假的,提供给您正在测试的类以满足其要求,但在单元测试中会被忽略。
Mock 是提供给您正在测试的类的假货, 将作为单元测试的一部分进行检查以验证功能。
例如,您正在测试的MyClass 类可能会同时使用本地记录器和第三方网络服务作为其操作的一部分。您将创建一个FakeLogger 和一个FakeWebService,但它们的使用方式决定了它们是存根还是模拟。
FakeLogger 可能用作存根:它被提供给MyClass 并伪装成记录器,但实际上忽略了所有输入,否则只是为了获取MyClass正常运行。您实际上并没有在单元测试中检查FakeLogger,就您而言,它可以让编译器关闭。
FakeWebService 可能用作 mock:您将其提供给 MyClass,并在您的一个单元测试中调用 MyClass.Foo(),它应该调用第三方网络服务。为了验证这是否发生,您现在检查您的 FakeWebService 以查看它是否记录了它应该接收的呼叫。
请注意,其中任何一个都可以颠倒过来,具体取决于您在特定单元测试中要测试的内容。如果您的单元测试正在测试正在记录的内容,那么您可以创建一个FakeLogger,它会尽职尽责地记录它所告诉的所有内容,以便您可以在单元测试期间对其进行询问;现在这是一个模拟。在同一个测试中,您可能不关心何时调用第三方 Web 服务;你的 FakeWebService 现在是一个存根。因此,如何填写 fake 的功能取决于它是否需要用作存根或模拟,或两者兼而有之。
总结(直接引用书中的内容):
fake 是一个通用术语,可用于描述存根或模拟对象,因为它们看起来都像真实对象。 . . .基本区别在于存根不能通过测试。模拟可以。
剩下的就是实现细节了。
【讨论】: