什么是对象模拟?何时需要?
许多人在编写单元测试时都使用Mock对象。什么是模拟对象?为什么我需要一个?我需要模拟对象框架吗?
解决方案
回答
它使我们可以测试项目的一部分如何与其余部分交互,而无需构建整个项目并可能丢失重要部分。
编辑:维基百科的一个很好的例子:它允许我们预先测试代码,就像汽车设计师使用碰撞测试假人来测试事故中汽车的行为一样。
回答
对象模拟是一种从接口,抽象类或者具有虚拟方法的类中创建"虚拟"或者模拟对象的方法。它允许我们将其中一种包装在自己的定义中以进行测试。对于制作要测试的特定代码块所依赖的对象很有用。
我喜欢使用的一种流行的叫做Moq,但是还有很多其他诸如RhinoMock之类的东西,我不知道。
回答
模拟对象使我们可以对照正在编写的内容以及抽象细节(例如访问资源(磁盘,网络服务等))进行测试。然后,该模拟让我们假装是该外部资源,类或者任何其他内容。
我们实际上并不需要模拟对象框架,只需扩展我们不想在测试中担心的功能的类,并确保我们要测试的类可以使用模拟对象而不是真实对象(将其传递给通过构造函数或者设置器之类的东西。
练习将显示模拟什么时候有用,什么时候没有帮助。
编辑:模拟资源特别重要,因此我们不必在测试过程中依赖它们的存在,并且可以模拟它们如何存在及其响应的详细信息(例如模拟FileNotFoundException或者缺少的Web服务) ,或者Web服务的各种可能的返回值)...都没有涉及到缓慢的访问时间(模拟比测试中访问此类资源要快得多)。
回答
对象模拟用于将依赖项排除在单元测试之外。
有时我们会遇到" SelectPerson"之类的测试,该测试将从数据库中选择一个人并返回一个Person对象。
为此,通常需要对数据库有依赖性,但是使用对象模拟可以使用模拟框架模拟与数据库的交互,因此它可能会返回一个看起来像从数据库返回的数据集,然后可以进行测试代码,以确保它能够处理将数据集转换为人员对象的过程,而不是使用它来测试与数据库的连接是否存在。
回答
另一个用途是它可以让我们针对系统中尚未构建的其他部分进行测试。例如,如果班级依赖于其他班级,而该班级是其他人正在使用的功能的一部分,则我们可以只要求一个几乎完整的界面,对该界面进行编程,并按自己希望的方式模拟细节。然后,确保我们对接口的假设是正确的(无论是在开发过程中,还是在功能完成后)。
回答
已经有几个人回答了"什么",但是我想到了几个简单的"为什么":
- 性能因为单元测试应该快速,所以测试与网络,数据库或者其他时间密集型资源交互的组件,如果使用模拟对象完成,则无需为此付出代价。节省下来的钱很快就累了。
- 协作如果我们正在编写一个很好封装的代码,需要与其他人的代码进行交互(尚未编写,或者正在并行开发中,这是一种常见情况),则可以一次使用模拟对象来执行代码接口已经达成共识。否则,直到其他组件完成后,代码才可能开始进行测试。
回答
Do I need a Mock Object Framework?
当然不是。有时,手工编写模拟游戏可能会非常乏味。但是对于简单的事情,这一点也不坏。将"最后负责时刻"的原理应用于模拟框架,只有在向自己证明手写模拟比其价值更大的麻烦时,才应从手写模拟转换为框架。
如果我们只是开始模拟,那么直接跳入框架至少会使学习曲线翻倍(我们可以将曲线翻倍吗?)。当我们花了一些手工编写模拟程序的项目时,模拟框架将变得更加有意义。
回答
模拟框架是否有用,部分取决于所编写代码的语言。使用静态语言时,我们需要付出更多的努力才能使编译器诱使模拟对象代替真实的对象。在诸如Python,Ruby或者Javascript之类的动态类型语言中,通常可以将方法添加到任意对象或者类上,并将其作为参数传递-这样,框架将增加的价值要少得多。
回答
用于.net单元测试的2个推荐的模拟框架是Typemock Isolator和Rhino Mock。
在下面的链接中,我们可以看到Typemock的解释,说明为什么需要用于单元测试的模拟框架。