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


当前回答

存根是一个简单的伪对象。它只是确保测试顺利进行。 mock是更聪明的存根。您验证您的测试通过了它。

其他回答

如果你把它比作调试:

Stub类似于确保一个方法返回正确的值 Mock实际上就像进入方法,在返回正确值之前确保里面的所有内容都是正确的。

Stub

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

Mock

模拟是测试的一部分,你必须根据你的期望来设置。mock并不是预先设定好的,所以您可以在测试中使用它。模拟在某种程度上是在运行时确定的,因为设置期望的代码必须在它们执行任何操作之前运行。

mock和stub的区别

使用模拟编写的测试通常遵循初始化->设置期望->练习->验证模式进行测试。而预先编写的存根将遵循初始化->练习->验证。

mock和stub之间的相似性

这两种方法的目的都是为了消除对类或函数的所有依赖项的测试,从而使您的测试在试图证明的内容方面更加集中和简单。

从论文模拟角色,而不是对象,由jMock的开发人员:

存根是返回罐装的产品代码的虚拟实现 结果。Mock对象充当存根,但也包括到的断言 测量目标对象与其邻居的交互作用。

所以,主要的区别是:

在存根上设置的期望通常是通用的,而在mock上设置的期望可能更“聪明”(例如,在第一次调用时返回this,在第二次调用时返回this等)。 存根主要用于设置SUT的间接输入,而mock可用于测试SUT的间接输入和间接输出。

综上所述,同时也试图驱散福勒文章标题中的困惑:mock是存根,但它们不仅仅是存根。

存根是为测试目的而构建的伪对象。mock是记录预期调用是否有效发生的存根。

他使用的通用术语是测试替身(想想特技替身)。Test Double是一个通用术语,用于为测试目的替换生产对象的任何情况。杰拉德列出了各种各样的替身:

Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists. Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example). Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent(also called Partial Mock). Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.