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],怎么弄成上角标捏?