自动化单元测试框架EasyMock分析及其应用

2014-12-12 08:58陈丽萍丁智敏
巢湖学院学报 2014年6期
关键词:单元测试字节示例

陈丽萍 张 勇 丁智敏

(巢湖学院计算机与信息工程学院,安徽 巢湖 238000)

1 引言

单元测试是极限编程的基础[1,2],单元测试的目的是保证每个程序模块能够正确运行。然而在实施单元测试驱动开发过程中,往往和被测模块交互的系统内某个模块或系统外实体尚未开发出来,此时可借助Mock Objects技术[3]。它从测试中分离了外部不需要的因素并且帮助开发人员专注于被测试的功能[4]。EasyMock框架[5]是Mock Objects技术的实现框架。它通过使用动态代理提供对接口和类创建Mock对象,并利用Mock对象模拟协同模块,从而使单元测试顺利进行。在开发时,将EasyMock、Junit集成到IDE中可方便的完成自动化测试[6]。本文在总结EasyMock框架的特点基础上,介绍了基本测试框架和分析了功能优缺点,并且针对缺点给出了相应的解决方案。

图1 EasyMock功能类

2 Easymock框架介绍

EasyMock[7]拥有很多的API函数,可以直接用在测试程序中,其主要的功能类结构如图1所示:

2.1 EasyMock类

EasyMock框架中与用户联系最紧密的类EasyMock类,该类提供了create,replay和verify mock对象等静态方法以及一系列的标准的参数匹配器。

2.2 IMocksControl接口

IMocksControl主要用于创建Mock对象,并负责管理Mock对象。

2.3 IExpectionSetters接口

IExpectionSetters接口主要是对Mock对象期望调用的方法进行一些相关的设置。

2.4 MocksControl类

MocksControl类主要提供了用于添加Mock对象的预期行为和实际调用的方法。

3 EasyMock框架应用

通过EasyMock创建Mock对象,并应用Mock对象来模拟外部协同模块,完成单元测试,需经历五个步骤。如图2所示:

图2 EasyMock应用步骤

3.1 创建Mock对象

首先创建被模拟模块的Mock对象,这里可以通过两种方式来完成。一种是使用EasyMock的creatMock方法直接创建;另一种是通过Easy-Mock类的createControl方法,先创建IMockControl对象,进而创建Mock对象。

3.2 录制Mock对象预期行为

接下来录制Mock对象的预期行为即为创建的Mock对象设定预期的方法调用和方法调用所产生的输出。

3.3 设置对象为replay状态

接着在使用Mock对象进行实际的测试前,需要将Mock对象的状态切换为replay状态。设置Mock对象为replay状态可以使用replay方法。

3.4 执行测试并检查返回结果

之后是执行需要测试的业务代码并检查代码是否返回正确的结果。

3.5 验证

最后是验证。它来验证整个过程中,Mock对象是否真正完成了record阶段的设定。

4 EasyMock分析与解决方案

4.1 EasyMock优缺点分析

Easymock通过检查附加给测试响应的断言来验证测试的结果和交互行为是通过还是失败,有大量的Junit的断言可供选择。软件结构的设计会导致Easymock框架的使用情况。具体优缺点分析如下:

4.1.1 EasyMock的优点

(1)EasyMock提供了动态构建Mock对象的方法,而无需开发人员额外实现Mock对象的代码,很大程度上减少了工作量。

(2)EasyMock可以完成多种Mock对象的测试场景。例如:当真实协同对象实际还不存在(如需要和其他开发人员开发的模块交互);当真实协同对象行为难于触发(如根据需要制造网络故障)等。

4.1.2 EasyMock的缺点

(1)EasyMock通过创建Proxy的方式来实现的Mock对象。因而Mock对象不能访问静态方法,这就造成EasyMock不能模拟静态方法。

(2)EasyMock通过创建Proxy的方式来实现的Mock对象,同时Java的封装特性,使得Mock对象不能访问私有方法和final方法。这就造成EasyMock不能模拟私有方法和final方法。

(3)EasyMock 不能对 Object类的 equals(),hasCode()、toString()方法模拟。 也就是说,Easy-Mock对这几种方法模拟时,无法改变其行为,它们仍旧按照默认的方式执行。此问题还有待于进一步的研究和分析。

4.2 针对EasyMock缺点的具体解决方案

EasyMock不能模拟静态方法。为了克服该缺点,这里可以通过整合EasyMock和PowerMock。PowerMock使用CGLib来操纵字节码来实现静态方法的Mock对象,因此可以对静态方法模拟支持[8]。因此在Mock方法时,使用EasyMock模拟普通方法,用PowerMock去模拟静态方法。Easy-Mock和PowerMock的结合可以更好地实现测试。

EasyMock不能模拟私有方法和final方法。为了解决该问题,可以通过使用字节码技术修改class文件中字节码的关键词,将私有方法变为公有方法和final修饰符去掉。在这里借助Java的字节码操作工具javassist,因为javassist可以在不需要了解虚拟机指令前提下,使用java编码形式动态对类转换、修改class中的方法。这样可以将含有final或private修饰符的类在被当前JVM加载前对此类修改。这样去除final和private标识符后,进而使用EasyMock进行测试。

5 应用EasyMock框架测试及结果分析

5.1 测试示例

5.1.1 示例程序 1

使用EasyMock框架对一个应用程序测试。这里的应用程序结构设计如图3所示:

图3 结构设计(1)

这里待测试类为Calculator,Calculator类中add方法完成两个整数之和,而add方法使用了Math类的addInteger方法。Calculator类和Math类对应代码如下:

5.1.2 示例程序 2

使用框架对另一个应用程序测试。这里的应用程序结构设计如图4所示:

图4 结构设计(2)

这里待测试类为Calculator,Calculator类中add方法完成两个整数之和,而add方法使用了Math类的addInteger方法。Calculator类和Math类对应代码如下:

5.2 测试结果分析

这里测试平台为 Eclipse-sdk-3.3, 使用JUint4.10 和 EasyMock3.2。将 EasyMock 框架与注入解决方案后的EasyMock框架分别对示例程序1,2进行测试。

使用EasyMock框架和注入解决方案后的EasyMock框架对示例程序1测试,测试结果分别如图5的(a),(b)所示:

图5 对示例程序1测试结果

使用EasyMock框架和注入解决方案后的EasyMock框架对示例程序2测试,测试结果分别如图6 的(a),(b)所示:

图6 对示例程序2测试结果

由此可见,EasyMock框架在模拟对象时有一些限制:不能对静态方法、私有方法和final方法模拟,导致测试失败。而使用了注入解决方案后的EasyMock框架可以应用于更多的测试情况,应用范围更广。

6 结束语

由于IT界对测试驱动开发技术的持续关注与偏爱,软件单元测试也成为人们研究的热点,EasyMock是单元测试的Mock工具之一。本文研究了EasyMock测试框架和应用;关注该工具在实际测试中的可行性,并且根据实际的需要采用整合Powermock框架和利用字节码操作工具javassist对类文件的修改来减少EasyMock框架的Mock对象的限制,测试结果证明了更好地满足实际的需要。

[1]Erickson J,Lyytinen K,Siau K.Agile Modeling,Agile Software Development,and Extreme Programming:The State of Research[J].Journal of Database Management,2005,(4):88-100.

[2]Mordinyi R,Kuhn E,Schatten A,Towards an Architectural Framework for Agile Software Development[C]//International Conference and Workshops on Engineering of Computer Based Systems.American,2010:276-280.

[3]Mackinnon T,Freeman S,Craig P.Endo-Testing:Unit Testing with Mock Objects[C]//Proceeding of the eXtreme Programming and Flexible .Italy,2000:21-23.

[4]Jafadeesh Nandigam,Tao Yonglei.Using mock object frameworks to teach object-oriented design principles[J].Journal of Computing Sciences in Colleges,2010,(1):40-48.

[5]Tammo,Freese.EasyMock:Dynamic Mock Objects for Junit[C]//Proceedings of the 3rd International Conference on Extreme Programming and Agile Processes in Software Engineering.Italy,2002:1-5

[6]Petar Tahchiev,Felipe Leme,Vincent Massol,et al.Junit实战[M].王魁,译.北京:人民邮电出版社,2012:96-129.

[7]EasyMock 官方网站[EB/OL].(2013-7-11)[2014-1-29]http://www.easymock.org/.

[8]PowerMock 官方网站.[EB/OL].(2013-11-19)[2014-1-29]http://www.Powermock.org/.

猜你喜欢
单元测试字节示例
No.8 字节跳动将推出独立出口电商APP
2019年高考上海卷作文示例
常见单位符号大小写混淆示例
No.10 “字节跳动手机”要来了?
常见单位符号大小写混淆示例
“全等三角形”错解示例
简谈MC7字节码
一年级上册第五单元测试
一年级上册一、二单元测试
第五单元测试卷