java

位置:IT落伍者 >> java >> 浏览文章

用StrutsTestCase测试Struts应用程序


发布日期:2019年11月01日
 
用StrutsTestCase测试Struts应用程序

Struts测试概述

一个具有良好系统架构的JEE应用程序至少有三层组成即表现层商业层和系统

集成层(包括数据存取以及和其他系统集成)目前Struts是应用比较广泛实现MVC模式应用于表现层的一种技术 在这里面Struts Action主要用来完成一些简单的数据校验转换以及流程转发控制(注意:这里流程不是业务规则) 因此在对整个应用程序进行测试时我们同时也要测试Struts Action

但是测试Struts Action相对测试简单的JavaBean是比较困难因为Struts是运行在Web服务器中 因此要测试Struts Action就必须发布应用程序然后才能测试 我们想象一下对于一个拥有上千个JSP page和数百甚至数千Java Classes的大规模应用程序要把他们发布到诸如Weblogic之类的应用服务器再测试需要多少的时间和硬件资源? 所以这种模式的测试是非常费时费力的

所以如果有一种办法能够不用发布应用程序不需要Web服务器就能象测试普通Java Class一样测试Struts Action那就能极大地加强Struts的可测试性能使应用程序测试更为容易简单快速 现在这个工具来了这就是StrutsTestCase

StrutsTestCase 概述

StrutsTestCase 是一个功能强大且容易使用的Struts Action开源测试工具它本身就是在大名鼎鼎的JUnit基础上发展起来的因此通过和JUnit结合使用能极大加强应用程序的测试并加快应用程序的开发

StrutsTestCase提供了两者测试方式模仿方式和容器测试方式 所谓模仿方式就是有StrutsTestCase本身来模拟Web服务器 而容器测试方式则需要Web服务器 本文要讨论的是前者原因很简单不需要Web服务器就能象测试普通的Java Class一样测试Struts Action

准备StrutsTestCase和Struts Action/ActionForm/Config

StrutsTestCase是一个开源工具可以到下载 目前最新版本是

如果你使用Servlet就下载StrutsTestCasejar使用Servlet的就下载StrutsTestCasejar

另外StrutsTestCase本身就是从JUnit继承的所以你还需要下载JUnit

在本文中我们用一个简单的例子来做测试 假设我们有一张表Hotline(country varchar()pno varchar())

我们要做的是根据输入条件从这张表检索相应的记录检索条件是country

Value Object:

package sample;

public class HotlineDTO implements Serializable{

private String country = ;

private String pno = ;

/**

* Method HotlineActionForm

*

*

*/

public HotlineDTO () {

super();

}

public void setCountry(String country) {

untry = country;

}

public void setPno(String pno) {

thispno = pno;

}

public String getCountry() {

return (untry);

}

public String getPno() {

return (thispno);

}

}

ActionForm:

package sample;

import orgapachestrutsactionActionForm;

public class HotlineActionForm extends ActionForm{

private String country = ;

private String pno = ;

/**

* Method HotlineActionForm

*

*

*/

public HotlineActionForm() {

super();

}

public void setCountry(String country) {

untry = country;

}

public void setPno(String pno) {

thispno = pno;

}

public String getCountry() {

return (untry);

}

public String getPno() {

return (thispno);

}

}

Action Class:

public class SearchHotlineAction extends Action {

public ActionForward execute(ActionMapping mapping ActionForm form HttpServletRequest request

HttpServletResponse response) throws Exception {

String target = ;

try{

//调用HotlineDAO检索hotline

String country=((HotlineActionForm)form)getCountry();

List hotlineList = HotlineDAOgetHotlineList(country);

if(hotlineList!=null && hotlineListsize()>){

requestsetAttribute(hotlineListhotlineList);

target = hotlineList;

}else{

target = notfound;

}

}catch(Exception ex){

}

}

Struts Config:

<strutsconfig>

<formbeans>

<formbean name=hotlineActionForm type=sampleHotlineActionForm />

</formbeans><actionmappings>

<action path=/SearchHotline

name=hotlineActionForm

type=sampleSearchHotlineAction

scope=request

validate=false>

<forward name=hotlineList path=/hotlineListjsp/>

<forward name=notfound path=/searchHotlinejsp/>

</action>

<actionmappings>

<strutsconfig>

初试StrutsTestCase

当采用模拟方式时所有的StrutsTestCase测试Class都是从MockStrutsTestCase继承下来的

下面我们就创建一个最简单的测试Class

public class SearchHotlineAction extends MockStrutsTestCase {

public void setUp()throws Exception{

}

public void tearDown()throws Exception{

}

public void testSearchHotline() throws Exception{

setRequestPathInfo(/SearchHotlinedo);

addRequestParameter(country CN);

actionPerform();

}

}

上面的Class相信用过JUnit的朋友都很熟悉

好了一个简单的测试例子就完成了如果你用的是Eclipse就选择RunRunJUnitNew就可以直接运行不需要发布你的程序不需要任何的Web服务器支持就可以测试Struts Action这就是StrutsTestCase带来的好处下面简单地介绍一下它是怎么工作的

在上面的例子中我们调用setRequestPathInfo()告诉StrutsTestCase我们要模拟JSP调用SearchHotlinedo这个Action并且调用addRequestParameter()增加了一个参数country最后调用actionPerform()运行

看到这里大家发现一个问题没有? 在上面Action的源代码里我们是通过

String country=((HotlineActionForm)form)getCountry();

也就是ActionForm来取得输入的参数值可我们在testSearchHotline()方法里并没有设置ActionForm?

那么它是怎么出来的呢? 其实大家如果熟悉Struts的运行流程的话就知道JSP接受用户的输入并发请求时都是类似这样//hostname/servletName?param=value¶m=value 只是Struts接受到这些参数后再根据Struts Config里的Action和ActionForm的映射把他们转为ActionForm后传给Action的

在上面的例子我们只是简单地运行了Action那么Action是否正确执行以及返回的结果是不是我们想要的呢?

我们继续完善一下testSearchHotline()这个Method

public void testSearchHotline() throws Exception{

setRequestPathInfo(/SearchHotlinedo);

addRequestParameter(country CN);

actionPerform();

verifyNoActionErrors();

verifyForward(hotlineList);

assertNotNull(requestgetAttribute(hotlineList));

List hotlineList = (List) requestgetAttribute(hotlineList);

for (Iterator it = erator();ithasNext();){

}

}

我们在actionPerform()后增加了几行语句来断定Struts Action是否正确执行

verifyNoActionErrors() 判断Action里没有任何的Action;

verifyForward(hotlineList) 判断Action确实转发到hotlineList;

assertNotNull(requestgetAttribute(hotlineList)) 判断Action确实返回了hotlineList并且不为空

到这里我们已经基本上讨论完了StrutsTestCase的核心部分 从头到尾我们没有发布应用程序也不需要Web服务器对我们来讲Struts Action就象普通的Java Class一样容易调试测试这就是StrutsTestCase给我们带来的方便

深入StrutsTestCase

除了以上我们用到的几个断定和校验方法外StrutsTestCase还提供了其他几个方法便于我们测试Struts Action 下面我一一讲述具体的大家可以参考文档

verifyActionErrors/Messages 校验ActionActionServlet controller 是否发送了ActionError或ActionMessage 参数为ActionError/Message Key

verifyNoActionErrors/Messages 校验ActionActionServlet controller 没有发送ActionError或ActionMessage

VerifyForward 校验Action是否正确转发到指定的ActionForward

VerifyForwardPath 校验Action是否正确转发到指定的URL

verifyInputForward 校验Action是否转发到Action Mapping里的input属性

verifyTilesForward/verifyInputTilesForward和以上类似应用程序使用到tiles时用的

关于Webxml和StrutsConfigxml

缺省情况下StrutsTestCase认为你的Webxml和strutsconfigxml的路径分别是:

/WEBINF/webxml和/WEBINF/strutsconfigxml

假如你的webxml/strutsconfigxml的路径是d:/app/web/WEBINF/webxml(strutsconfigxml)的话就需要把d:/app/web加到classpath

假如你的struts config是strustconfigmodulexml那么必须调用setConfigFile()设置你的struts config文件

结束语

JEE应用程序的测试在开发过程中占有相当重要的位置利用StrutsTestCase能极大方便你测试基于Struts的应用程序

上一篇:Struts开源之关于VO、PO概念的理解

下一篇:Spring笔记和小结(四)