1、之前我们的项目struts2版本是使用struts2.1.18,他使用struts2-junit-pugin-2.1.8.1.jar进行测试的时候完全可以,而且很方便,参考地址,http://gsdhaiji-cai.iteye.com/blog/1404230
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],怎么弄成上角标捏?