??xml version="1.0" encoding="utf-8" standalone="yes"?>
作?叶枫(http://blog.matrix.org.cn/page/叶枫)
原文:[http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html]http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html[/url]
关键?Struts StrutsTestCase
一、Struts试概述
一个具有良好系l架构的J2EE应用E序臛_有三层组?卌现层,商业层和pȝ
集成?包括数据存取以及和其他系l集?,目前,Struts是应用比较广?实现MVC2模式应用于表现层的一U技? 在这里面,Struts Action主要用来完成一些简单的数据校验,转换,以及程转发控制(注意:q里程不是业务规则). 因此在对整个应用E序q行试?我们同时也要试Struts Action.
但是,试Struts Action相对试单的JavaBean是比较困?因ؓStruts是运行在Web服务器中, 因此要测试Struts Action必d布应用程序然后才能测? 我们惌一?对于一个拥有上千个JSP page和数癄x千Java Classes的大规模应用E序,要把他们发布到诸如Weblogic之类的应用服务器再测?需要多的旉和硬件资? 所以这U模式的试是非常费时费力的.
所?如果有一U办法能够不用发布应用程?不需要Web服务器就能象试普通Java Class一h试Struts Action,那就能极大地加强Struts的可试性能,使应用程序测试更为容?单快? 现在q个工具来了,q就是StrutsTestCase.
二、StrutsTestCase 概述
StrutsTestCase 是一个功能强大且Ҏ使用的Struts Action开源测试工?
它本w就是在大名鼎鼎的JUnit基础上发展v来的。因此通过和JUnitl合
使用能极大加强应用程序的试q加快应用程序的开?
StrutsTestCase提供了两者测试方?模仿方式和容器测试方? 所谓模仿方式就是有StrutsTestCase本n来模拟Web服务? 而容器测试方式则需要Web服务? 本文要讨论的是前?原因很简单,不需要Web服务器就能象试普通的Java Class一h试Struts Action.
三、准备StrutsTestCase和Struts Action/ActionForm/Config
StrutsTestCase是一个开源工?可以到http://strutstestcase.sourceforge.net下蝲. 目前最新版本是2.1.3,
如果你用Servlet2.3׃载StrutsTestCase213-2.3.jar,使用Servlet2.4的就下蝲StrutsTestCase213-2.4.jar.
另外StrutsTestCase本n是从JUnitl承?所以你q需要下载JUnit3.8.1.
在本文中,我们用一个简单的例子来做试. 假设我们有一张表Hotline(country varchar2(50),pno varchar2(50)),
我们要做的是Ҏ输入条g从这张表索相应的记录.索条件是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) {
this.country = country;
}
public void setPno(String pno) {
this.pno = pno;
}
public String getCountry() {
return (this.country);
}
public String getPno() {
return (this.pno);
}
}
ActionForm:
package sample;
import org.apache.struts.action.ActionForm;
public class HotlineActionForm extends ActionForm{
private String country = "";
private String pno = "";
/**
* Method HotlineActionForm
*
*
*/
public HotlineActionForm() {
super();
}
public void setCountry(String country) {
this.country = country;
}
public void setPno(String pno) {
this.pno = pno;
}
public String getCountry() {
return (this.country);
}
public String getPno() {
return (this.pno);
}
}
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 = HotlineDAO.getHotlineList(country);
if(hotlineList!=null && hotlineList.size()>0){
request.setAttribute("hotlineList",hotlineList);
target = "hotlineList";
}else{
target = "notfound";
}
}catch(Exception ex){
....
}
}
Struts Config:
<struts-config>
<form-beans>
<form-bean name="hotlineActionForm" type="sample.HotlineActionForm" />
.......
</form-beans>
<action-mappings>
<action path="/SearchHotline"
name="hotlineActionForm"
type="sample.SearchHotlineAction "
scope="request"
validate="false">
<forward name="hotlineList" path="/hotlineList.jsp"/>
<forward name="notfound" path="/searchHotline.jsp"/>
</action>
.....
<action-mappings>
........
<struts-config>
四、初试StrutsTestCase
当采用模拟方式时,所有的StrutsTestCase试Class都是从MockStrutsTestCasel承下来?
下面我们创Z个最单的试Class.
public class SearchHotlineAction extends MockStrutsTestCase {
public void setUp()throws Exception{
}
public void tearDown()throws Exception{
}
public void testSearchHotline() throws Exception{
setRequestPathInfo("/SearchHotline.do");
addRequestParameter("country", "CN");
actionPerform();
}
}
上面的Class怿用过JUnit的朋友都很熟?
好了,一个简单的试例子完成了,如果你用的是Eclipse选择Run-Run...-JUnit-New可以直接运?不需要发布你的程?不需要Q何的Web服务器支?可以测试Struts Action,q就是StrutsTestCase带来的好?下面单地介绍一下它是怎么工作?
在上面的例子?我们调用setRequestPathInfo()告诉StrutsTestCase我们要模拟JSP调用SearchHotline.doq个Action,q且调用addRequestParameter()增加了一个参数country.最后调用actionPerform()q行.
看到q里,大家发现一个问题没? 在上面Action的源代码里我们是通过String country=((HotlineActionForm)form).getCountry();
也就是ActionForm来取得输入的参数?可我们在testSearchHotline()Ҏ里ƈ没有讄ActionForm?
那么它是怎么出来的呢? 其实大家如果熟悉Struts的运行流E的话就知道,JSP接受用户的输入ƈ发请求时
都是cMq样的http://hostname/servletName?param1=value1¶m2=value2. 只是Struts接受到这?br />参数后再ҎStruts Config里的Action和ActionForm的映把他们转ؓActionForm后传lAction?
在上面的例子,我们只是单地q行了Action,那么Action是否正确执行以及q回的结果是不是我们惌的呢?
我们l箋完善一下testSearchHotline()q个Method.
public void testSearchHotline() throws Exception{
setRequestPathInfo("/SearchHotline.do");
addRequestParameter("country", "CN");
actionPerform();
verifyNoActionErrors();
verifyForward("hotlineList");
assertNotNull(request.getAttribute("hotlineList"));
List hotlineList = (List) request.getAttribute("hotlineList");
for (Iterator it = hotlineList.iterator();it.hasNext();){
....
}
}
我们在actionPerform()后增加了几行语句来断定Struts Action是否正确执行.
verifyNoActionErrors() -- 判断Action里没有Q何的Action;
verifyForward("hotlineList") -- 判断Action实转发到hotlineList;
assertNotNull(request.getAttribute("hotlineList")) -- 判断Action实q回了hotlineListq且不ؓI?br />
到这?我们已经基本上讨论完了StrutsTestCase的核心部? 从头到尾,我们没有发布应用E序,也不需要Web服务?Ҏ们来?Struts Actionp普通的Java Class一样容易调试测?q就是StrutsTestCasel我们带来的方便.
五、深入StrutsTestCase
除了以上我们用到的几个断定和校验Ҏ?StrutsTestCaseq提供了其他几个Ҏ便于我们试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属?br />verifyTilesForward/verifyInputTilesForward--和以上类?应用E序使用到tiles时用?br />
六、关于Web.xml和Struts-Config.xml
~省情况?StrutsTestCase认ؓ你的Web.xml和struts-config.xml的\径分别是:
/WEB-INF/web.xml?WEB-INF/struts-config.xml
1. 假如你的web.xml/struts-config.xml的\径是
d:/app/web/WEB-INF/web.xml(struts-config.xml)的话,需要把d:/app/web加到classpath.
2. 假如你的struts config是strust-config-module.xml,
那么必须调用setConfigFile()讄你的struts config文g
七、结束语
J2EE应用E序的测试在开发过E中占有相当重要的位|?利用StrutsTestCase能极大方便你试ZStruts的应用程?
]]>
修改面中应昄10个checkboxQ同时应该有5个已l被选中
详细实际问题Q?br /> Z满业务需要,从linux安装盘中的comps.xml中读取提供的服务所依赖的包
昄在页面上Q根据包的类型(default,mandatory,optionalQ决定显C的Ҏ
default默认选中Qmandatory不提供选择Qoptional为用户可?br />
在处理层Q采用struts的form来接受,定义string [] nodeRPMs接受卛_
接受后存在数据库里,然后d来在昄在页面上
在修攚w面,首先应该有全部的checkboxQ同时用户选中的应该已l被打勾Q这来自数据库读出的记录Q?l过中午的查找资?br />才知道可以用mutilbox解决q个问题
mutilbox会根据你d的值来讑֮
struts中的checkbox是单选的Q它的值应该只有true和false或者yes no或者on off之分Q?br />r如果希望使用一l可以多选的checkboxQ在struts中的面标签应该是html:multibox,它的用法Q?lt;html:multibox property="strArray" value="value1">或?br /> <html:multibox property="strArray">value2</html:multibox>
真正载页面上使用时可能是q样Q?br /><html:multibox property="strArray">a</html:multibox>
<html:multibox property="strArray">b</html:multibox>
<html:multibox property="strArray">c</html:multibox>
当然"strArray"一定是面相对应的formbean中的一个属性,q且应该是数l:
private String[] strArray; //提供get setҎ
q样Q如果我们在面上面选中了前两个Q则strArray.length=2;strArray[0]里面的值是a,strArray[1]里面的值是b;
如果我们把form中的strArray讄为strArray[0]="b",strArray[1]="c",则{到页面之后,面上只有后两项被选中
所以这样就可以解决问题?br />