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

时间:2009-01-21 00:33:19

标签: mocking rhino-mocks

我玩的不够,通常使用嘲讽,但我想知道这两者之间的区别是什么,以及何时在犀牛嘲笑中使用其中一种。

更新

我还在Ayende's words中找到了我的问题的答案:

存根和模拟之间的区别

您可以在本文中获得这些术语的实际定义:Mocks Aren't Stubs。我想从Rhino Mocks的角度来关注差异。

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

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

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

5 个答案:

答案 0 :(得分:145)

根据this

  

......简单地说,Mock和Stub对象之间存在差异   和RhinoMocks认识到允许我们更好地编写测试   陈述他们的目的。

     

模拟对象用于定义期望,即:在这种情况下我   期望方法A()用这样的参数调用。嘲弄   记录并验证这些期望。

     另一方面,Stubs有不同的目的:他们不记录   或验证期望,但允许我们“替换”行为,   “虚假”对象的状态,以便利用测试场景......

答案 1 :(得分:20)

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

存根

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

嘲笑

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

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

总结

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

这种差异仍然很重要吗?

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

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

你应该使用哪个?

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

答案 2 :(得分:7)

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

答案 3 :(得分:5)

对于Moq框架 - setup方法是STUB,其中Verify方法是Mock

答案 4 :(得分:0)

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