假货比Mocks好吗?

时间:2010-10-22 21:28:54

标签: c# unit-testing mocking fakeiteasy

我偶然发现了这个开源项目Fake It Easy,我不得不承认,它看起来非常有趣,但我怀疑,FIE假货和Moq Mocks有什么区别?是否有更好的特定用途?

编辑:

这个新框架是什么让它比Moq更好?

4 个答案:

答案 0 :(得分:90)

要说清楚,我创建了FakeItEasy所以我绝对不会说一个框架是否比另一个更好,我能做的是指出一些差异并激励为什么我创建了FakeItEasy。在功能上,Moq和FakeItEasy之间没有重大差异。

FakeItEasy没有“可验证”或“期望”它有断言但是,这些在测试的最后总是明确说明,我相信这使得测试更容易阅读和理解。它还有助于初学者避免多个断言(他们会在许多调用或模拟对象上设置期望)。

之前我使用过Rhino Mocks,我非常喜欢它,特别是在引入AAA语法之后,我确实更喜欢Moq的流畅API。我不喜欢Moq的是“模拟对象”,你必须使用mock.Object无处不在,我更喜欢Rhino-approach与“自然”模拟。每个实例看起来和感觉就像伪造类型的正常实例。我想要两全其美,而且我想看看当我完全放手时我能用语法做什么。我个人(显然)认为我创造了一个与两个世界中最好的混合的东西,但是当你站在巨人的肩膀上时,这很容易。

正如这里提到的那样,主要区别之一是术语,FakeItEasy首先被创建用于向初学者介绍TDD和嘲笑,并且不得不担心前面的模拟和存根之间的差异(你需要的方式)犀牛)在我看来并不是很有用。

我把很多注意力集中在异常消息上,只要看一下异常消息就可以很容易地判断测试中出错了什么。

FakeItEasy具有一些其他框架所没有的可扩展性功能,但这些功能还没有很好地记录下来。

FakeItEasy(希望)在模拟具有构造函数参数的类中更强一些,因为它具有解析虚拟值的机制。您甚至可以通过在测试项目中实现DummyDefinition(Of T)类来指定自己的虚拟值定义,这将由FakeItEasy自动获取。

语法是一个明显的区别,一个更好的主要是品味问题。

我确信我现在忘记了很多其他的差异(并且公平地说我从未在生产中使用Moq因此我对它的了解有限),我认为这些是最重要的差异

答案 1 :(得分:23)

测试中使用的术语可能会有些混乱。解释不同概念之间差异的最佳来源是Martin Fowler Mocks Aren't Stubs。总之, fake 是一个描述存根和模拟的通用术语。

答案 2 :(得分:10)

嘲弄中的术语可能令人困惑 - 有时甚至是非常不直观的。

因此,许多人提出了一个更简单的新术语,其中只有假货模拟存根

是所有可能类型的测试双打的通用术语,无论它们来自何处以及如何使用它们。

除此之外, fakes 仅在一个维度上区分:它们是否影响测试结果;或者,换句话说:你是否必须设置假的返回值,它们在测试执行期间以某种方式使用,或者它是一个' silent '对象,它只用于实现某些依赖。< BR />

存根 这是' silent '对象。

模拟 在测试执行中积极参与

除此之外,没有进一步的区别 - 这肯定有它的历史优点,但现在在很大程度上是反直觉和学术性的,它有点模糊了测试驱动开发的真正重要概念。

关于 Moq FakeItEasy 之间的比较:从概念的角度来看,两个框架大致相同 - 差异仅在API和术语 ...

托马斯

答案 3 :(得分:-3)

从我的观点来看,Fake不会取消Moc,例如我使用Dev Magic Fake伪造DAL和Business层,同时我在MVC中使用Mock来实现HTTPContext

var repoistory = new FakeRepository<ProductTypeForm, VendorForm>();
            repoistory.Save(productTypeForm);
            this.FillDropDown(new FakeRepository<VendorForm>());

在之前的代码中Dev Magic Fake将保存ProductTypeForm并从Dev Magic Fake中检索VendorForm并将其链接到ProductTypeForm,此保存操作可以是永久性的

有关Dev Magic Fake的更多信息,请参阅CodePlex: http://devmagicfake.codeplex.com

测试此方法我们必须模拟HTTP上下文

var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();

所以我使用假和模拟