struts2单元测试-2(使用EasyMock)
2、坑爹的是,在一个旧的系统中,同样导入struts2-junit-pugin-2.1.8.1.jar,发现不行,后来跟踪了一下源码才发现:
struts2版本是2.0.11存在:strutsTestCase这个类,它与struts2-junit-pugin-2.1.8.1.jar中strutsTestCase类冲突,而且连包名都相同,导致struts2-junit-pugin-2.1.8.1.jar这个包中的StrutsTestCase无法使用,后来直接换掉其他方式来测试。ps:有谁能告诉我方法,在struts2 2.0.11版本直接使用struts2-junit-pugin,小弟不胜感激,必定以身相许:)
3、使用了EasyMock方法处理[1],下载地址是
http://sourceforge.net/projects/easymock/files/EasyMock/
4、后来发现运行时候有一个问题,如下
java.lang.NoClassDefFoundError: org/objenesis/ObjenesisHelper
at org.easymock.internal.ObjenesisClassInstantiator.newInstance
需要下载下面一个jar包,
http://code.google.com/p/objenesis/downloads/detail?name=objenesis-1.1.jar&can=2&q=
5、例子:
1、测试基类BaseAcionTest.java(其他action的测试类,都是继承他)
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.easymock.EasyMock; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class BaseActionTest { protected ApplicationContext context; protected HttpServletRequest request; protected HttpServletResponse response; BaseAction baseAction; public BaseActionTest() { context = new FileSystemXmlApplicationContext("classpath*:applicationContext-test.xml"); this.request = EasyMock.createMock(HttpServletRequest.class); this.response = EasyMock.createMock(HttpServletResponse.class); ServletActionContext.setRequest(request); ServletActionContext.setResponse(response); } }
2、某一个测试类
@Test
public void testSave() throws IOException { //预期设置阶段record阶段,模拟一些初始动画 //这一步已经在父类中定义了,他依赖与request的初始化//需要下面这样传递参数才行 //直接使用request.addParameter();不行 //这面这个方法,是可以避免测试程序调用ajax方法,我们直接告诉他这个方法的返回值是什么,省去ajax调用,这里注释掉 //NetStandardAction netStandardAction = EasyMock.createMockBuilder(NetStandardAction.class).addMockedMethod("ajax").createMock(); NetStandardAction netStandardAction = new NetStandardAction(); EasyMock.expect(request.getParameter("name")).andReturn("hello"); EasyMock.expect(request.getParameter("netStandardId")).andReturn(""); this.request.setAttribute("ajaxInfo", "success"); EasyMock.expectLastCall(); //EasyMock.expect(netStandardAction.ajax("success")).andReturn("ajax"); //repay,你要测试的对象放在这里,在这个阶段将record阶段的录制操作,重新运行一遍 netStandardAction.setNetStandardService((NetStandardService)context.getBean("netStandardService")); EasyMock.replay(this.request); //EasyMock.replay(netStandardAction); String result = netStandardAction.saveNetStandard(); //verify阶段,用来验证我们的测试结果与交互 //调用了junit进行结果判断 //Assert.assertEquals("保存成功", "ajax", result); //验证request是否按照record阶段模拟运行了 EasyMock.verify(this.request); //EasyMock.verify(netStandardAction); }
3、NetStandardAction类:
//此类需要spring注入netStandardService public String saveNetStandard(){ String netStandardId=getParam("netStandardId"); String name=getParam("name"); if(isEmpty(netStandardId)){ NetStandard netStandard=new NetStandard(); netStandard.setName(name); netStandardService.save(netStandard); }else{ NetStandard netStandard=netStandardService.get(NetStandard.class,Integer.valueOf(netStandardId)); netStandard.setName(name); netStandardService.update(netStandard); } return ajax(SUCCESS); }
4、上面中的ajax方法
//这里的getRequest是获取当前request对象
public String ajax(String info) { getRequest().setAttribute("ajaxInfo",info); return "ajax"; }
5、总结一下:
首先感谢参考资料中的作者,他的文档太给力了:)
需要明白以下内容:
record->replay->verify这个过程
谁要事先录制(依赖的对象——次要测试对象,你用mock来模拟),测试对象(主要测试对象)
对于方法调用的顺序,要看:strict和nice这一节
对于有返回值和没有返回值,你需要怎么写
参考资料:
[1]:http://www.iteye.com/topic/834528
弱弱的问一下,正文中的[1],怎么弄成上角标捏?