Rhino Mocks 上的 mock 和 stub 有啥区别?

Posted

技术标签:

【中文标题】Rhino Mocks 上的 mock 和 stub 有啥区别?【英文标题】:What are the differences between mocks and stubs on Rhino Mocks?Rhino Mocks 上的 mock 和 stub 有什么区别? 【发布时间】:2010-10-02 14:21:54 【问题描述】:

我玩得还不够多,通常使用模拟,但我想知道这两者之间有什么区别以及何时在 Rhino Mocks 上使用其中一个。

更新:

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

存根和模拟之间的区别 您可以在本文中获得这些术语的实际定义:Mocks Aren't Stubs。我想从 Rhino Mocks 的角度来关注不同之处。

模拟是我们可以设置期望的对象,它将验证期望的操作确实发生了。存根是您用来传递给被测代码的对象。您可以对其设置期望,因此它会以某些方式运行,但这些期望永远不会得到验证。存根的属性会自动表现得像普通属性一样,您不能对它们设置期望。

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

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

【问题讨论】:

What's the difference between faking, mocking, and stubbing?的可能重复 【参考方案1】:

根据this

... 简单来说,Mock 和 Stub 对象是有区别的 并且 RhinoMocks 认识到允许我们编写更好的测试 陈述他们的目的。

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

另一方面,存根有不同的用途:它们不记录 或验证期望,而是允许我们“替换”行为, “假”对象的状态,以便利用测试场景...

【讨论】:

我发现了另一个有用的帖子,它与这个问题的接受答案相同的信息 - martinfowler.com/articles/mocksArentStubs.html【参考方案2】:

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

存根

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

模拟

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

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

总结一下

模拟是带有实现的存根,它可以让我们测试副作用。

这种差异仍然重要吗?

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

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

你应该使用哪个?

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

【讨论】:

【参考方案3】:

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

【讨论】:

您似乎在说您的测试应该“检查”模拟的输出。如果这就是你所说的,那你就错了。不应该测试模拟;它在那里,因此您可以测试 other 代码。还是你的最后一句话有别的意思? 嗨,安德鲁,正如我所写的那样,使用 Mock 可以修复测试的输出,因此您不会对其进行测试。否则我已经写了 Mock 允许您检查交互(预期行为......; -) 好的,这更有意义。感谢您的澄清! >doesn't make assertion on stub 为什么在许多assertion libraries 中仍然存在方法又名should have been called with 来断言stub 参数。【参考方案4】:

如果是 Moq 框架 - setup 方法是 STUB,而 Verify 方法是 Mock

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于Rhino Mocks 上的 mock 和 stub 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rhino Mocks 模拟任意行为?

Rhino Mocks 默认返回类型?

Rhino Mocks:实例化 Mock 属性,以便 Expectation 可以引用它

Rhino Mocks - 使用 ref/out 参数模拟集合

使用 Rhino Mocks 保存到存储库

为啥我的 Rhino Mocks Partial Mock 方法调用没有被模拟?