我在单元测试中给出的任何阅读或建议总是暗示了Mock和Stub的定义之间的明显区别。我目前对这些定义的理解如下
模拟:将用于的假货 你的测试做出最后的断言
Stub:将用于的假货 你的测试来隔离依赖但是 不被断言
但是,Moq似乎只允许创建Mocks。框架中的Stub名称空间似乎已被折旧,建议使用Mock.SetupXXX。
我对此有何看法?或者是否有一般性的理解,模拟对象实际上可以用作存根?
也许我是迂腐的,只是我总是发现编程中的语言非常严格,而且更喜欢让我正确使用它,特别是当其他开发人员可能接管一个项目时。
答案 0 :(得分:15)
根据Moq project site,Moq提供:
使用简单的MockBehavior枚举对模拟行为进行粒度控制(无需了解模拟,存根,虚假,动态模拟等之间的理论差异)。
模拟,存根等之间缺乏区别是一个深思熟虑的设计决策;一个人喜欢的设计决定。如果我需要 true 模拟,我会在其上调用Verify()
。如果没有,则没有Verify()
。我喜欢简单,我没有发现自己错过了mock
和stub
之间的区别。
答案 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();
恕我直言,假货的味道之间的区别最好被认为是假货的功能之间的区别,而不是假货的类型,因为假货可以承担多重角色立刻(例如,可以同时是真正的模拟和破坏者),并且因为使用模拟框架不需要这样的区别。 (我应该在博客上发帖!)