这两天看了看单元测试辅助工具 NMock,找到两篇文章,看的时候脑袋晕晕沉沉的,为了强迫自己看完这两篇文章,就动手翻译了一下。
自从大学里过了 CET-4 后,英语基本就再也没有动过了,平常半通不通的看一些技术资料还没有问题,今天动手翻译才发现差的不是一点半点;水平有限,文中的错误在所难免,大家尽管拍砖,不过请不要人身攻击,谢谢。
转载请标明出处。
NMock简介
原文:http://confluence.public.thoughtworks.org/display/NMock/Introduction+to+NMock
by Hsue-Shen Tham
NetCobra 翻译
模拟对象(Mocking)
通常在进行单元测试的时候,开发人员常常会碰到这样一些情况:一些功能由于对其它类或系统组件有依赖而难以测试;通常用来解决这种问题的一项技术叫做模拟对象(mock objects)。模拟对象方法允许用模拟的版本来代替被依赖的类(dependent classes),这些模拟对象被传递给要测试的类后,依赖关系就被模拟的版本代替了,而被测试对象则仍然会以为自己所处理的是真实的对象。
以前模拟实例都是人工编写的,不过如今在Java世界和.Net世界都已经有很多工具和框架用于更方便地创建模拟对象;现在已经有很多的资料介绍手工或者使用一些常见Java模拟工具来创建模拟对象的优秀方法(fine art)了,这篇文章要介绍的是使用.Net的一个常见的模拟工具NMock在实现在.Net中的模拟对象测试。
静态 vs. 动态
模拟工具通常可以分为两类:静态的和动态的。对于静态模拟工具,被依赖从属类的模拟对象是作为外部的类生成的,这些类在编译时和被测试对象一起编译,确保类型安全;而动态模拟工具则不添加任何附加的类,通过在运行时动态实现模拟。因为动态模拟工具更容易使用,并且不生成附加的类,因此动态模拟工具比静态模拟工具更常见也更愿意被人们使用;不过相对于静态模拟而言,动态模拟不是类型安全的。
使用 NMock
NMock是一个基于动态代理的模拟工具,用于 C# 开发。NMock使用了代理模式,这允许类实现一个接口并以代理的方式将其它对象的调用转向。NMock生成的模拟是通过在运行时使用动态代理来实现的,这允许模拟对象动态的定义,并不需要添加任何附加的类。
通常,一个模拟的实现基于被依赖的接口而创建;NMock支持对接口和类的模拟,另外它还支持属性模拟。下面是一个使用NMock的快速教程:
示例
现在我们来做一个简单的“Hello”例子,测试 Hello 类的 Greet() 方法,Hello 类依赖于一个 Person 对象,并将根据 Person 的名字向对应的账号发送祝贺(Greet)。这个例子很简单,其实用不到模拟对象,不过用来理解 NMock 是很合适的。
就像我们看到的,Hello 类对 IPerson 接口有依赖。
在我们继续对 Hello 类的开发之前,让我们来学习一些关于 NMock 的基础知识。使用 NMock 很容易根据一个给定的接口或类来创建一个模拟对象;创建的过程有三步,首先你要实例化一个 Mock 对象,构建时要将你要模拟的接口或类的类型传递给 Mock 对象作为构建参数;然后,你需要记录 Mock 对象的行为并最终通过 Mock 对象的属性来获得一个模拟类型的示例。下面是一个最简单的窗体的模拟对象,该模拟对象基于 IPerson 接口创建,没有记录任何行为。
这是一个简略的预期设置的方法列表:
Expect(string methodName, object[] args)
ExpectAndReturn(string methodName, object returnVal, object[] args)
ExpectAndThrow(string methodName, Exception exceptionVal, object[] args)
ExpectNoCall(string methodName)
现在设置好所有的基本条件,我们就可以简单的在对 Hello 类的测试中应用 NMock 了。
这就是我们的测试类: