我读过各种关于测试中模仿和存根的文章,包括Martin Fowler的《Mocks Aren't Stubs》,但我仍然不理解其中的区别。


当前回答

下面是对每一个的描述,然后是真实世界的样本。

Dummy - just bogus values to satisfy the API. Example: If you're testing a method of a class which requires many mandatory parameters in a constructor which have no effect on your test, then you may create dummy objects for the purpose of creating new instances of a class. Fake - create a test implementation of a class which may have a dependency on some external infrastructure. (It's good practice that your unit test does NOT actually interact with external infrastructure.) Example: Create fake implementation for accessing a database, replace it with in-memory collection. Stub - override methods to return hard-coded values, also referred to as state-based. Example: Your test class depends on a method Calculate() taking 5 minutes to complete. Rather than wait for 5 minutes you can replace its real implementation with stub that returns hard-coded values; taking only a small fraction of the time. Mock - very similar to Stub but interaction-based rather than state-based. This means you don't expect from Mock to return some value, but to assume that specific order of method calls are made. Example: You're testing a user registration class. After calling Save, it should call SendConfirmationEmail.

存根和Mock实际上是Mock的子类型,两者都交换了实际实现和测试实现,但出于不同的、特定的原因。

其他回答

存根是向SUT返回值的测试double。

模拟是测试用于验证SUT正确调用依赖项的双重测试。

而且,mock通常是存根

我在阅读《单元测试的艺术》时,偶然发现了以下定义:

fake是一个通用术语,可以用来描述存根或模拟对象(手写或其他),因为它们看起来都像真实的对象。赝品是存根还是mock取决于它在当前测试中的使用方式。如果它用于检查交互(根据其断言),则它是一个模拟对象。否则,它就是存根。

有很多很棒的答案,我喜欢这个,所以我把它做成了一个表格。

Dummy Stub Mock Fake
API O O O O
States X O O O
Values X X O O
Behavior X X X O

在codeschool.com的课程《Rails僵尸测试》中,他们给出了这些术语的定义:

Stub

用于将方法替换为返回指定结果的代码。

Mock

带有调用方法的断言的存根。

因此,正如Sean Copenhaver在他的回答中所描述的那样,不同之处在于mock设置了期望(即做出断言,关于是否或如何调用它们)。

Mock只是测试行为,确保调用了特定的方法。 Stub是特定对象的可测试版本(本质上)。

你说的苹果方式是什么意思?