Moq中的单元测试Mock / Stub定义

时间:2010-09-08 22:46:09

标签: unit-testing testing moq

我在单元测试中给出的任何阅读或建议总是暗示了Mock和Stub的定义之间的明显区别。我目前对这些定义的理解如下

  

模拟:将用于的假货   你的测试做出最后的断言

     

Stub:将用于的假货   你的测试来隔离依赖但是   不被断言

但是,Moq似乎只允许创建Mocks。框架中的Stub名称空间似乎已被折旧,建议使用Mock.SetupXXX。

我对此有何看法?或者是否有一般性的理解,模拟对象实际上可以用作存根?

也许我是迂腐的,只是我总是发现编程中的语言非常严格,而且更喜欢让我正确使用它,特别是当其他开发人员可能接管一个项目时。

4 个答案:

答案 0 :(得分:15)

根据Moq project site,Moq提供:

  

使用简单的MockBehavior枚举对模拟行为进行粒度控制(无需了解模拟,存根,虚假,动态模拟等之间的理论差异)。

模拟,存根等之间缺乏区别是一个深思熟虑的设计决策;一个人喜欢的设计决定。如果我需要 true 模拟,我会在其上调用Verify()。如果没有,则没有Verify()。我喜欢简单,我没有发现自己错过了mockstub之间的区别。

答案 1 :(得分:11)

Martin Fowler撰写了一篇好文章Mocks Aren't Stubs,我认为这一点很明确。

模拟用于行为验证,而存根提供虚假数据并且通常参与状态验证。

答案 2 :(得分:3)

只是这是一种愚蠢的讨论。

重要的是你使用模拟/存根来断言测试中你需要的东西,而不是断言你不需要的东西。

答案 3 :(得分:0)

事实上,Moq可以创建真正的存根。来自Moq Quick Start page

* Setup a property so that it will automatically start tracking its value (also known as Stub):

  // start "tracking" sets/gets to this property
  mock.SetupProperty(f => f.Name);

  // alternatively, provide a default value for the stubbed property
  mock.SetupProperty(f => f.Name, "foo");


  // Now you can do:

  IFoo foo = mock.Object;
  // Initial value was stored
  Assert.Equal("foo", foo.Name);

  // New value set which changes the initial value
  foo.Name = "bar";
  Assert.Equal("bar", foo.Name);

* Stub all properties on a mock (not available on Silverlight):

  mock.SetupAllProperties();

恕我直言,假货的味道之间的区别最好被认为是假货的功能之间的区别,而不是假货的类型,因为假货可以承担多重角色立刻(例如,可以同时是真正的模拟和破坏者),并且因为使用模拟框架不需要这样的区别。 (我应该在博客上发帖!)