??xml version="1.0" encoding="utf-8" standalone="yes"?>
“单元试出错了,但到底是谁的错。我的?他的Q?#8221;Q这U情冉|然违反了试的独立性原?/span>。出现这U情况得这个测试无法确切的指出是那个单元出C问题Q照成了排错的困难,而且也浪费了旉。同Ӟq分的将单元的测试代码依赖于其他单元Q也照成了其他一些很现实的问题:
在所依赖的单元完成之前,无法利的编写单元测试?/span>
产生环境的依赖性,如运行一?/span>HttpServletRequest处理器的试代码必须启动一?/span>servlet容器?/span>
所有这些问题,都可以?/span>Mock Object来解冟뀂用它的前提是Q所依赖单元的接口必d义清楚。?/span>EasyMock正是Zq一目的而生的?/span>
使用目的
通过模拟unit test所需要的lgQ已辑ֈ隔离各个unit test的目的。目前的版本1.1Q它所需要的环境?/span>jdk1.3.1以上?/span>junit3.8.1以上?/span>
可以?/span>http://sourceforge.net/projects/easymock/处下载?/span>
用法
1. EasyMock采用“记录-----回放”的工作模式,基本使用步骤Q?/span>
- 创徏Mock对象的控制对?/span>Control?/span>
- 从控制对象中获取所需要的Mock对象?/span>
- 记录试Ҏ中所使用到的Ҏ和返回倹{?/span>
- 讄Control对象?#8220;回放”模式?/span>
- q行试?/span>
- 在测试完毕后Q确?/span>Mock对象已经执行了刚才定义的所有操作?/span>
2. 使用举例Q假N要测试的对象?/span>RequestUtilQ所需要测试的Ҏ?/span>getBoolean。此时我们需要模拟一?/span>HttpServletRequest对象?/span>
public void testGetStringHttpServletRequestString() {
public void testGetBoolean() {
//创徏Mock对象的控制器
MockControl control= MockControl.createControl( HttpServletRequest.class);
//获取Mock对象
HttpServletRequest mock= (HttpServletRequest)control.getMock();
//讄getBoolean中要使用的方法和q回?/span>
control.expectAndReturn( mock.getParameter( "test"), null);
//讄控制器ؓreplay模式
control.replay();
//执行试
assertNull( RequestUtil.getString( mock, "test"));
//认
control.verify();
}
}
通过EasyMockQ执行这D|试代码完全不需要启动一?/span>servlet容器Q在命o行的方式下即可完成,非常的方ѝ?/span>
3. 记录需要用的Mock的行为。在使用一?/span>Mock对象之前Q需要设|我们要用到的方法,以及每个Ҏ的返回倹{对于那些没有设|的ҎQ一旦调用(控制器处?/span>replay模式Q,EasyMock׃抛出异常。记录一个方法,通常可以分成2?/span>Q首先,如同使用正常对象调用q个ҎQ然后,使用控制器的setReturnValue函数讄卛_。在1.1中,提供?/span>expectAndReturn函数Q?/span>2步可以合而ؓ一。主要的函数大致如下Q?/span>
- expectAndReturnQ设|期望调用的函数Q以及返回?/span>
- expectAndThrowQ设|期望调用的函数Q同时期望该ơ调用抛出异?/span>
- setReturnValueQ设|上一ơ调用的q回|如上ơ调用时Q?/span>request.getparameter( “test”)Q此处设|?/span>request.getparameter( “test”)的返回|
- setThrowableQ设|上ơ调用抛出的异常
?/span>EasyMock中还可以讄调用所执行的次敎ͼ具体l节请参见对应的javaDoc?/span>
4. 使用举例Q?/span>
MockControl control= MockControl.createControl( HttpServletRequest.class);
HttpServletRequest mock= (HttpServletRequest)control.getMock();
mock.getParameter( "test");
//讄W一ơ调?/span>request.getParameter的返回?/span>
control.setReturnValue( null, 1);
//讄W二ơ调?/span>request.getParameter的返回?/span>
control.setReturnValue("this is a test", 1);
control.replay();
assertEquals( RequestUtil.getString( mock, "test", "haha"), "haha");
assertEquals( RequestUtil.getString( mock, "test"), "this is a test");
control.verify();
5. ?/span>Mock对象使用l束后,务必调用控制器的verify函数Q以认Mock对象的方法得C调用?/span>
6. 调用Ҏ的次序,使用Strict。有Ӟ试代码依赖于被依赖lg的方法的ơ序。如在测试与数据库相关代码时Q测试代码很有可能是q样的次序:先打开数据库链接,执行操作Q关闭链接。ؓ了更好的试q样的代码,可以使用MockControl.createStrictControl()来创Z个严格的Mock对象控制器,在其中,他会规定Mock出来的对象的调用ơ序?/span>
以上?/span>EasyMock的主要用,至于其他的用法,请参见具体的文?/span>
PSQ?/font>当自己动手实?/span>Mock对象Ӟ不要?/span>Mock对象中实C务逻辑?/span>