什么是不同类型的测试替身及其用途?

What are different types of test doubles and their uses?

我正在学习有关测试驱动开发的在线课程,并遇到了测试替身的概念。根据课程中测试替身的定义:

Test Doubles : Test doubles are objects that are used in unit tests as replacement to the real production system collaborators.

我知道测试替身是什么意思了。但后来有人提到有各种类型的测试替身。课程中提到的是:

Dummy : Objects that can be passed around as necessary but do not have any type of test implementation and should never be used.

Fake : These objects generally have a simplified functional implementation of a particular interface that is adequate for testing but not for production.

Stub : These objects provide implementation with canned answers that are suitable for the tests.

Spies : These objects provide implementation that record the values that were passed in so they can be used by the tests.

Mocks : These objects are pre-programmed to expect specific calls and parameters and can throw exceptions when necessary.

我以前使用过 mock,对它们是什么以及如何使用它们有一个简要的了解。虽然我对其他提到的测试替身类型感到困惑。

有人可以帮助我了解这些类型的测试替身之间的区别以及何时使用它们吗?

有用的文献,

Dummy 是一种奇怪的情况,因为您正在使用 dummy,因为被测代码实际上并不使用 dummy;换句话说,系统的组成需要你提供一些多余的元素。通常,这暗示您正在测试的逻辑应该可以通过更具体的接口访问。

当测试场景要求被测代码从某些依赖项中获取值时,通常会使用存根和伪造。

一个stub很专注;它不会假装在内部做正确的事情,而只是 returns 一些固定的答案。例如,您可以使用存根来模拟特定的故障模式。

Fake 的命名很糟糕 - 它是依赖项的真实实现,只是针对测试(小型、确定性、内存中)进行了优化,而不是针对生产(规模)进行了优化。在某些圈子中,您会听到 substitute,而不是“fake”。

当您试图确定您的代码是否将正确的信息发送到依赖项,而无需耦合到该依赖项的成本时,通常会使用间谍和模拟。

间谍通常会保留他们在测试期间收到的消息的历史记录,稍后可以根据预期的消息列表对其进行验证。模拟是该想法的更积极表达,其中在场景 运行 时对被测代码的行为做出断言,而不是事后。

我推荐 Bob 叔叔的博客文章 "The Little Mocker" 的简短阅读,它不仅很好地解释了区别test doubles 的类型和这些类型之间的区别,而且 解释了在什么情况下使用什么类型 用易于理解的 代码说明样本.

参见:https://blog.cleancoder.com/uncle-bob/2014/05/14/TheLittleMocker.html