测试Struts Action相对比较困难,因为Struts是运行在Web服务器中,因此要测试Struts Action 就必须发布应用程序然后才能测试,换言之,我们必须要有Web容器的支持。我们想象一下,对于一个拥有上千个JSP page和数百甚至数千Java Classes的大规模应用程序,要把他们发布到诸如Weblogic之类的应用服务器在测试,需要多少的时间和硬件资源?所以这种模式的测试是非常费时费力的。
所以,如果有一种办法能够不用发布应用程序,不需要Web服务器就能象测试普通Java Class一样测试Struts Action,那就能极大地加强Struts的可测试性能,使应用程序测试更为容易,简单快速。现在这个工具来了,这就是Struts TestCase.
Struts TestCase是一个开源工具,可以到http://strutstestcase.sourceforge.net下载。另外StrutsTestCase本身就是从JUnit继承的,所以你还需要下载JUnit3.8.1。
下面就以一个简单的LogonAction为例测试一下:
public class LogonAction extends Action {
public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request,HttpServletResponse response) {
DynaValidatorForm dynaForm = (DynaValidatorForm)form;
String name = (String)dynaForm.get("username");
String password = (String)dynaForm.get("password");
if(name.equals("wangxq")&&password.equals("wangxq")){
request.setAttribute("valid_user",form);
return mapping.findForward("admin");
}
return mapping.findForward("success");
}
}
LogonAction的简单说明:从Logon的页面中输入用户名和密码,在LogonAction中做判断,并且作相应的跳转。对其的测试代码如下:
public class LogonActionTest extends MockStrutsTestCase {
protected void setUp() throws Exception {
super.setUp();
setContextDirectory(new File("WebRoot")); // 设置WEB-INF的上级目录,让程序可以找到struts-config.xml文件
}
protected void tearDown() throws Exception{
super.tearDown();
}
public void testNoParameters(){
setRequestPathInfo("/logon");
actionRerform();
verifyInputForward();
String[] actionErrors = {"errors.required","errors.required"};
verifyActionErrors(actionErrors);
verifyInputForward();
}
public void testOneParameters(){
setRequestPathInfo("/logon");
addRequestParameter("username","wangxq");
actionPerform();
// 校验Action是否转发到Action Mapping里的input属性
verifyInputForward();
String[] actionErrors = {"error.required"};
verifyActionErrors(actionErrors);
verifyInputForward();
}
public void testSuccessAdmin(){
// 设置Request的请求,说明该Request请求的是哪一个Action,或者说,请求的是哪一个.do文件。
setRequestPathInfo("/logon");
//将参数和其对应的值加入到request中,相当于是action对应的formbean传过来的值,即用户在登录界面输入的值。
addRequestParameter("username","wangxq");
addRequestParameter("password","wangxq");
//执行这个请求,即执行action中对应的execute的方法。
actionFerform();
//验证forward的名字是否正确,即有没有跳转到预期的页面。
verifyForward("admin");
//验证没有任何的ActionErrors.
verifyNoActionErrors();
}
public void testSuccessLogon(){
setRequestPathInfo("/logon");
addRequestParameter("username","aaa");
addRequestParameter("password","bbb");
actionPerform();
verifyForward("success");
verifyNoActionErrors();
}
}
补充说明其中的一些方法:
verifyActionErrors/Messages——校验ActionServlet controller是否发送了ActionError或ActionMessage参数为ActionError/Message Key
verifyNoActionErrors/Messages——校验ActionServlet controller没有发送了ActionError或ActionMessage
VerifyForward——校验Action是否正确转发到指定的ActionForward.
VerifyForwardPath——校验Action是否正确转发到指定的URL.
verifyInputForward——校验Action是否转发到Action Mapping里的input属性。
其他的方法可以参考具体的文档说明。
还有一点需要说明:
关于web.xml和struts-config.xml
缺省情况下,StrutsTestCase认为你的web.xml和struts-config.xml路径分别是:
/WEB-INF/web.xml和/WEB-INF/struts-config.xml
1.假如你的web.xm/struts-config.xml的路径是d:/application/web/WEB-INF/web.xml的话,就需要把d:/application/web加到classpath.或者更简单的方法是setContextDirectory(new File("web"))这样就可以找到了。
2.假如你的struts config是strust-config-module.xml,那么必须调用setConfigFile()设置你的struts config文件
深入使用:
<action path="/handle" input="/handle.do?method=setUp" name="handleForm" type="handleAction" scope="session" parameter="method" validate="true">
<forward name="CurPage" path="handle" />
</action>
这段配置文件中,使用了parameter="method"的配置,这样在测试的时候就需要设置一下,测试代码应加入:
addRequestParameter("method","setUp");
这样,在执行actionPerform()时,程序就自动进入setUp的方法,执行该方法的测试。
另外,也可以用EasyMock来进行Action测试。