关于模仿:Rhino Mocks上的模拟和存根之间有什么区别?

What are the differences between mocks and stubs on Rhino Mocks?

我没有玩这个并且通常使用嘲讽,但我想知道这两者之间的差异以及何时使用Rhino Mocks中的一个或另一个。

更新:

我也用Ayende的话来找到我的问题的答案:

短柱和模具之间的区别

您可以在本文中获得这些术语的实际定义:模拟不是存根。我想从Rhino Mocks的角度来关注差异。

模拟是一个我们可以设置期望的对象,它将验证预期的操作确实已经发生。存根是您用于传递给测试代码的对象。您可以设置它的期望,因此它会以某种方式起作用,但这些期望永远不会得到验证。存根的属性将自动表现为普通属性,您无法设置它们的期望。

如果要验证测试代码的行为,您将使用具有适当期望的模拟,并验证。如果您只想传递可能需要以某种方式执行的值,但不是此测试的焦点,则将使用存根。

重要信息:存根永远不会导致测试失败。


按此

... Put simply there is a difference between Mock and Stub objects
and RhinoMocks recognizes that allowing us to write tests that better
state their purpose.

Mock objects are used to define expectations i.e: In this scenario I
expect method A() to be called with such and such parameters. Mocks
record and verify such expectations.

Stubs, on the other hand have a different purpose: they do not record
or verify expectations, but rather allow us to"replace" the behavior,
state of the"fake"object in order to utilize a test scenario ...


一般来说,单元测试调用函数和方法,然后检查是否发生了预期的行为。这些函数和方法可能需要参数。我们使用存根和模拟来满足这些参数。我们有时也可以模拟全局对象。

存根

Stub是一个很小的假对象,您的测试可以将其用作参数以使函数调用工作。这使我们可以验证被测函数的行为。它不会让我们验证任何副作用,因为存根没有实现。

嘲弄

模拟是一个带有实现的存根。如果我们的测试函数与我们的模拟对象交互,我们可以验证模拟是否已经按照我们的预期进行了交互。

例如,假设我们有一个模拟User对象,我们想验证我们的session.login方法是否有效,我们可能想检查user.lastLoggedIn是否已设置。我们可以创建一个实现此方法的模拟用户。当我们调用session.login时,我们可以声明user.lastLoggedIn具有我们期望的状态。

总结一下

mock是一个带有实现的存根,它允许我们测试副作用。

这种差异仍然很重要吗?

更像是明喻和隐喻之间的区别,存根和模拟之间的区别是微妙的和历史的,并且可能与测试世界中的不同社区和哲学有关,而不是任何主要的技术差异。

它们代表了稍微不同的测试方法。模拟可以像存根一样编写。存根通常可以扩展为模拟。

你应该用哪个?

您可能会发现您开始创建存根,之后您可能会发现需要为某些对象创建完整的模拟。您可能想要随意模拟所有内容,或者您??可能只想在需要的地方进行模拟。


模拟和存根之间的区别:
使用存根,您可以修复单元测试的输入:因此您的单元测试不会在存根上进行断言
和Stub通过重写某些方法的实现来修复虚假对象的行为。
使用Mock,您可以修复单元测试的输出:因此,您的单元测试通过检查模拟对象中的内部交互来对Mocking对象产生期望。


在Moq框架的情况下 - setup方法是STUB,其中Verify方法是Mock


我注意到的一件事是,当我使用MockRepository.GenerateMock时,我需要明确设置对特定方法调用的期望来拦截该调用。使用存根,只要它是虚拟的,它似乎会自动拦截任何方法。