Unit testing Moq中的单元测试模拟/存根定义

Unit testing Moq中的单元测试模拟/存根定义,unit-testing,testing,moq,Unit Testing,Testing,Moq,我在单元测试方面得到的任何阅读或建议都表明,Mock和Stub的定义有着明显的区别。我目前对这些定义的理解如下 冒牌货:一种将在游戏中使用的假货 你的测试是为了做出最后的断言 存根:一个假的,将用于 隔离依赖项的测试,但 不可断言 但是,Moq似乎只允许创建模拟。由于建议使用Mock.SetupXXX,框架中的存根名称空间似乎被贬低了 我对这件事的理解有什么遗漏吗?或者人们普遍认为模拟对象实际上只能用作存根 也许我有点迂腐,只是我一直觉得编程语言非常严格,我更喜欢正确使用它,特别是当其他开发人员

我在单元测试方面得到的任何阅读或建议都表明,Mock和Stub的定义有着明显的区别。我目前对这些定义的理解如下

冒牌货:一种将在游戏中使用的假货 你的测试是为了做出最后的断言

存根:一个假的,将用于 隔离依赖项的测试,但 不可断言

但是,Moq似乎只允许创建模拟。由于建议使用Mock.SetupXXX,框架中的存根名称空间似乎被贬低了

我对这件事的理解有什么遗漏吗?或者人们普遍认为模拟对象实际上只能用作存根


也许我有点迂腐,只是我一直觉得编程语言非常严格,我更喜欢正确使用它,特别是当其他开发人员可能要接管一个项目时。

我只是觉得这是一种愚蠢的讨论


重要的是,您使用mock/stub来声明您在测试中需要声明的内容,而不声明您不需要声明的内容。

Martin Fowler写了一篇很好的文章,我认为这篇文章清楚地说明了区别

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

根据标准,最低起订量提供:

通过简单的枚举对模拟行为进行细粒度控制(无需了解模拟、存根、伪造、动态模拟等之间的理论区别)


模拟、存根等之间缺乏区别,这是一个深思熟虑的设计决策;我个人更喜欢的设计决策。如果我需要一个真正的mock,我会在上面调用
Verify()
。如果没有,则没有
Verify()
。我喜欢它的简单性,而且我没有发现自己遗漏了
mock
stub
之间的区别。事实上,Moq可以创建真正的stub。从:


依我看,假货口味之间的区别最好被认为是这些假货功能之间的区别,而不是假货类型之间的区别,因为假货可能一次扮演多个角色(例如,可以同时成为真正的假货和破坏者),并且使用假货框架不需要这样的区别。(我应该在博客上写这件事!)

我不同意埃格拉修斯。测试应该非常容易阅读、消化和理解其他开发人员正在执行的操作。语言在这方面起着关键作用。@WDuffy当然,但我看到的方式是,在测试代码中已经清楚地传达了这些信息。区分存根和模拟有助于向测试读者表明哪些消息与当前测试(预期)和附带测试(存根)相关但行为验证与所涉及的数据相关,即使数据以不同的方式保存。当然,这些术语的定义是明确的,但这并不意味着它保证在这种区别明显模糊的地方也不灵活。@eglasius,当然。即使我想把它用作存根,我也不介意一个库认为它给了我一个它称之为mock的东西。我只会根据我的使用情况适当地命名变量。+1绝对同意,如果团队认为传达区别很重要,那么变量的命名将澄清这一点。
* 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();