38

最近,围绕 .NET 世界中所有不同的模拟框架进行了相当大的宣传。我还没有完全理解他们的伟大之处。编写我自己需要的模拟对象似乎并不难。特别是在 Visual Studio 的帮助下,我可以快速编写一个类来实现我想要模拟的接口(它为我自动生成几乎所有内容),然后为我的测试所需的方法编写一个实现。完毕!为什么要为了节省几行代码而费尽心思去理解一个模拟框架。还是一个模拟框架不仅仅是为了节省代码行数?

4

10 回答 10

32

一旦我终于掌握了模拟对象的窍门,我意识到它们对于单元测试至关重要,原因与双盲测试或对照组对于科学试验必不可少:它们隔离了您实际测试的内容。

如果您正在测试一个通过其他接口进行大量交互的类,您不仅可以节省模拟每个接口的代码行,而且您还可以获得执行诸如“抛出异常”之类的能力调用了意外的方法”或“如果这些方法被乱序调用,则异常”。您可以使用模拟框架变得非常复杂,尽管我很快承认学习曲线很大,但当您加快速度时,它们将有助于使您的单元测试更加彻底而不会臃肿。

于 2008-11-18T21:29:20.123 回答
12

您实际上在问题中确定了模拟框架的关键点之一。您自己编写模拟代码的事实不是开发人员应该关心的。模拟框架以编程方式为您提供接口的实现,而且它们是功能性的(基于您的模拟设置)。

例如,如果您正在测试一个 ICustomerDAO,并且您想对某个方法进行 14 次不同结果的测试,您会怎么做?手动实现 14 个不同的类?我怀疑有人愿意这样做。

当您不关心它们是否真正起作用时,模拟使您能够定义类的某些部分会发生什么,例如在您想要它们时抛出异常,返回零结果并确保您正确处理,等等...

它们是一个很棒的单元测试工具。

于 2008-11-18T21:36:58.720 回答
8

以前可能有帮助的问题:
什么是模拟,什么时候应该使用它?
Mockist 与经典 TDD

我发现使用模拟框架可以让我更快地生成测试,并且可以更好地验证我期望在测试中发生的事情实际上是发生。我过去曾自己实施过存根或伪造品。我发现我需要生成特定于我想要的测试的存根,这需要很多时间。我可以使用模拟框架更快地创建相同的测试。好的支持以简单的语法生成假货、存根或模拟。

需要一段时间才能掌握它,我有一段时间避免使用它,但由于@Chamelaeon 所述的原因,现在不会尝试在没有模拟框架的情况下工作。

于 2008-11-18T21:36:32.623 回答
4

Roy Osherove对 Mock Frameworks 进行了一项民意调查,在评论部分,有一个关于是否需要 Mock Framework 的讨论(尽管很简短)。

我个人一直按照您所说的手动进行操作,并且效果很好,但这主要是出于习惯,而不是对模拟框架的普遍看法。

于 2008-11-18T21:28:58.347 回答
3

好吧,我当然不认为你需要一个模拟框架。它与任何其他框架一样,最终旨在为您节省一些时间和精力。您还可以执行诸如滚动您自己的常见数据结构(如堆栈和队列)之类的事情,但通常只使用内置于您选择的语言的编译器/IDE 附带的类库中的那些不是更容易吗?

我确信使用模拟框架还有其他令人信服的理由,尽管我将把它留给 TDD 和单元测试专家来回答。

于 2008-11-18T21:26:28.040 回答
2

出于同样的原因,您不会尝试在没有 NUnit 的情况下编写单元测试。模拟框架将帮助您验证数百个单元测试的状态和行为。花费 2 周左右的时间来加快速度并真正帮助您专注于需要测试的内容是值得的。

于 2008-11-18T21:54:41.260 回答
2

关于模拟框架让我困扰的一件事是“给定 i/p 的函数应该 o/p”通过

when(mock.someMethod("some arg")).thenReturn("something");

语句分布在许多单元测试类中。

让我用一个例子来详细说明。假设有一个 DAO 接口函数 getEmp(int EmpID) 在将员工 ID 作为参数传递时返回一个员工对象。假设这个函数被 10 个不同的单元测试类模拟。现在,如果将来更改此函数以返回更新版本的 Employee 对象,则必须访问 10 个不同的类中的每一个来更新此更改。

缺点如下...

a) 我不知道如何找出所有模拟这个函数的类,以便我可以去更新这个变化。

b) 我现有的使用模拟 DAO 对象的测试用例仍然幸福地没有意识到 DAO 接口发生的变化,因为模拟没有改变,因此继续保持绿色。理想情况下,如果我自己编写了一个模拟类并在任何地方使用它,我将只有一个地方可以更新 Employee 对象的新版本。此外,一旦我在这个地方更新,我所有使用模拟的现有测试用例都会中断,然后我会确切地知道我需要去哪些地方并为新的员工对象进行更新。

对我的观点有任何想法..

于 2010-03-04T14:48:32.547 回答
0

模拟框架的好处之一是它允许对被模拟的对象设置期望。有了期望,我就可以设置各种条件来运行正在测试的代码。

于 2008-11-18T21:40:32.397 回答
0

隔离框架或模拟框架允许您测试您想要的代码,而无需依赖它。它可以进行短期运行测试,允许您快速调试,并轻松地围绕代码构建测试安全网。不同的框架有不同的特性,如前所述——它是一个工具,你应该为工作选择合适的工具。

于 2009-04-24T08:48:05.817 回答
0

我使用 rhino 模拟作为模拟框架。我和其他 5 位开发人员在一个为期 8 个月的大型企业应用程序中使用了它。我们在项目中使用了 tdd。它值得吗?我猜。使用模拟是否有如此巨大的卖点,以至于我必须在每个项目中都使用它?在我看来,没有。这不是必需的,它只是一个工具,如果你想尝试一下就可以使用。有些项目你可以推出自己的模拟类,因为这里有些人说他们更喜欢 - 这更容易。其他项目更大,可能需要一个模拟框架。关键词(在我看来)是可能需要...你需要多少代码覆盖率?对我来说,这是使用模拟的另一个考虑因素。我用 tdd/rhino 模拟做的项目要求我们有 80% 的代码覆盖率,所以模拟帮助我们实现了这一目标。

于 2012-04-21T20:55:22.753 回答