Unit testing 为什么我的单元测试需要一个模拟框架?

Unit testing 为什么我的单元测试需要一个模拟框架?,unit-testing,mocking,Unit Testing,Mocking,最近,围绕.NET世界中所有不同的模拟框架,有相当多的炒作。我还没有完全理解他们的伟大之处。写我自己需要的模拟对象似乎并不难。特别是在VisualStudio的帮助下,我可以很快地编写一个类来实现我想要模拟的接口(它会自动为我生成几乎所有内容),然后为我测试所需的方法编写一个实现。完成!为什么仅仅为了节省几行代码而费劲地理解一个模拟框架呢。或者,模拟框架不仅仅是为了保存代码行吗 我当然不认为你需要一个模拟框架。这是一个与其他任何框架一样的框架,它的最终设计目的是为您节省一些时间和精力。您也可以使

最近,围绕.NET世界中所有不同的模拟框架,有相当多的炒作。我还没有完全理解他们的伟大之处。写我自己需要的模拟对象似乎并不难。特别是在VisualStudio的帮助下,我可以很快地编写一个类来实现我想要模拟的接口(它会自动为我生成几乎所有内容),然后为我测试所需的方法编写一个实现。完成!为什么仅仅为了节省几行代码而费劲地理解一个模拟框架呢。或者,模拟框架不仅仅是为了保存代码行吗

我当然不认为你需要一个模拟框架。这是一个与其他任何框架一样的框架,它的最终设计目的是为您节省一些时间和精力。您也可以使用自己的常用数据结构(如堆栈和队列),但使用所选语言的编译器/IDE附带的类库中内置的数据结构通常不是更容易吗

我确信使用模拟框架还有其他令人信服的原因,不过我会让TDD和单元测试专家来回答。

对模拟框架进行了调查,在评论部分,有一个关于是否需要模拟框架的讨论(尽管很简短)


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

一旦我最终掌握了模拟对象的窍门,我意识到它们对于单元测试至关重要,这与双盲测试或控制组对于科学试验至关重要的原因相同:它们隔离了您实际测试的内容


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

前面的问题可能会有所帮助:

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


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

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

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

mock使您能够定义当您不关心类的某些部分是否实际工作时,它们会发生什么情况,比如在需要时抛出异常、返回零结果并确保正确处理这些异常等等


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

模拟框架的一个优点是,它允许对被模拟的对象设定期望值。有了这些期望,我就可以设置各种条件来执行正在测试的代码。

出于同样的原因,如果没有NUnit,您就不会尝试编写单元测试。模拟框架将帮助您在数百个单元测试中验证状态和行为。花2周左右的时间来加快速度是值得的,它确实可以帮助您专注于需要测试的内容。

一个隔离框架或允许您测试所需的代码,而无需依赖项。它有助于短时间运行测试,允许您快速调试,并轻松地围绕代码构建测试安全网。不同的框架有不同的特性,正如前面所说的,它是一种工具,您应该为工作选择正确的工具

关于模拟框架,有一件事困扰着我,那就是通过

当(mock.someMethod(“some arg”)。然后返回(“something”)

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

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

缺点如下

a) 我不知道如何找出所有模仿此函数的类,以便我可以更新此更改

b) 我现有的使用mock-DAO对象的测试用例仍然没有意识到DAO接口发生的变化,因为mock没有改变,因此仍然是绿色的。 理想情况下,如果我编写了一个模拟类,我的