StrutsTestCase for JUnit是Junit TestCase類(lèi)的擴(kuò)展,提供基于Struts框架的代碼測(cè)試裝置。StrutsTestCase同時(shí)提供Mock 對(duì)象方法和Cactus方法用來(lái)實(shí)際運(yùn)行Struts ActionServlet,你既可以通過(guò)運(yùn)行servlet引擎來(lái)測(cè)試,也可以不通過(guò)它。因?yàn)镾trutsTestCase使用ActionServlet控制器來(lái)測(cè)試你的代碼,因此你不僅可以測(cè)試Action對(duì)象的實(shí)現(xiàn),而且可以測(cè)試mappings,from beans以及forwards聲明。
使用StrutsTestCase不啟動(dòng)servlet容器來(lái)測(cè)試struts應(yīng)用程序(容器外測(cè)試)也屬于Mock對(duì)象測(cè)試,但是與EasyMock不同的是,EasyMock是提供了創(chuàng)建Mock對(duì)象的API,而StrutsTest則是專(zhuān)門(mén)負(fù)責(zé)測(cè)試Struts應(yīng)用程序的Mock對(duì)象測(cè)試框架。
除了容器外測(cè)試,StrutsTest也可以很方便的用容器內(nèi)的測(cè)試。
StrutsTestCase當(dāng)前的版本是StrutsTest2.1.2,支持Servlet2.2和2.3的規(guī)范,并且支持Struts1.1,Cactus1.6.1和Junit3.8.1。在這個(gè)版本中不支持Struts1.0。如果需要測(cè)試struts1.0的應(yīng)用程序,對(duì)應(yīng)的版本是StrutsTest2.0?梢詮膆ttp://sourceforge.net/projects/strutstestcase/下載。
首先應(yīng)從StrutsTestCase主頁(yè)下載該工具,解壓后會(huì)有一個(gè)JAR文件,還有一個(gè)例子以及API DOC。編寫(xiě)StrutsTestCase時(shí)需將這個(gè)JAR文件引入到工程中(和Struts中的JAR文件放在一起),此外由于是對(duì)JUnit的擴(kuò)展,因此還必須將Junit.jar引入到工程中。
上面已經(jīng)介紹過(guò)有兩種測(cè)試方法,下面分別來(lái)簡(jiǎn)單說(shuō)明:
1) MockStrutsTestCase(Mock對(duì)象測(cè)試):通過(guò)模擬容器來(lái)進(jìn)行測(cè)試。MockStrutsTestCase用一套HttpServlet mock對(duì)象在不需要運(yùn)行Servlet引擎的情況下來(lái)模擬容器環(huán)境。
2) CactusStrutsTestCase(In-container testing):在真實(shí)運(yùn)行的容器中通過(guò)使用Cactus測(cè)試框架進(jìn)行測(cè)試。
說(shuō)明:上述兩個(gè)類(lèi)都是對(duì)Junit TestCase的擴(kuò)展。如果要將Mock對(duì)象測(cè)試方法改為Cactus方法,只需要將我們所定義子類(lèi)的父類(lèi)由MockStrutsTestCase改為CactusStrutsTestCase即可,而不需要更改內(nèi)部代碼。
命名規(guī)則:對(duì)于類(lèi)的命名沒(méi)有嚴(yán)格的規(guī)范,但個(gè)人建議使用Test+要測(cè)試的Action名;方法名可以任意取,但注意一點(diǎn):系統(tǒng)只會(huì)自動(dòng)運(yùn)行以”test”開(kāi)頭的方法名來(lái)進(jìn)行測(cè)試。
下面通過(guò)一個(gè)我寫(xiě)的一個(gè)實(shí)例來(lái)說(shuō)明具體使用方法,先來(lái)看一個(gè)Action(RegisterAction.java)中的代碼:
package com.firefly;
import org.apache.struts.action.*;
import javax.servlet.http.*;
/**
* @author firefly
*/
public class RegisterAction extends Action{
public ActionForward execute(ActionMapping mapping,ActionForm form,
HttpServletRequest req, HttpServletResponse res){
RegisterForm rf = (RegisterForm)form;
//String userName = rf.getUserName();
String password1 = rf.getPassword1();
String password2 = rf.getPassword2();
if(password1.equals(password2)){
try{
return mapping.findForward("success");
}
catch(Exception e){
return mapping.findForward("failure");
}
}
return mapping.findForward("failure");
}
}
功能很簡(jiǎn)單,即查看兩次輸入的密碼是否相同,相同則轉(zhuǎn)到success,否則轉(zhuǎn)到failure。下面是測(cè)試代碼(TestRegisterAction.java):
package com.firefly;
import servletunit.struts.*;
/**
* @author firefly
*/
public class TestRegisterAction extends MockStrutsTestCase{
public void setUp() throws Exception{
super.setUp();
}
public void tearDown() throws Exception{
super.tearDown();
}
public TestRegisterAction(String testName){
super(testName);
}
public void testSuccessfulLogin(){
setRequestPathInfo("/register");
addRequestParameter("userName","hellking");
addRequestParameter("password1","123");
addRequestParameter("password2","123");
actionPerform();
verifyForward("success");
}
public void testFailedLogin(){
setRequestPathInfo("/register");
addRequestParameter("userName","hellking");
addRequestParameter("password1","123");
addRequestParameter("password2","");
actionPerform();
verifyForward("failure");
}
}
說(shuō)明:
1) 如果override了setUp()和tearDown()方法,那么必須在第一行顯示調(diào)用其父類(lèi)的相應(yīng)方法,原因很簡(jiǎn)單,父類(lèi)在這兩個(gè)方法中定義了很多內(nèi)容來(lái)保證程序能夠按照既定規(guī)則執(zhí)行,所以我們必須加載它。
2) 在測(cè)試方法中,我們需要做的第一件事是通知Struts在這個(gè)測(cè)試中要使用哪一個(gè)映射(mapping),我們指定一個(gè)和Struts mapping相關(guān)聯(lián)的路徑,這與Struts標(biāo)簽庫(kù)方法中使用的機(jī)制相同。
3) 我們接下來(lái)要做的是通過(guò)request對(duì)象傳遞form bean屬性,這同樣與Struts所做的相同。
4) 該到運(yùn)行action的時(shí)候了,我們通過(guò)使用actionPerform()方法來(lái)完成該任務(wù)。
5) 后要檢驗(yàn)的是程序運(yùn)行結(jié)果是否和我們所預(yù)期的一樣,通過(guò)調(diào)用verifyForward()方法來(lái)進(jìn)行確認(rèn)。這里還有可能用到其他一些方法,如:assertEquals(),assertNull(),verifyNoActionErrors(),verifyActionErrors()等等。
6) 即使你在test方法中不進(jìn)行任何測(cè)試,系統(tǒng)也不會(huì)提示任何錯(cuò)誤(這個(gè)與Action中execute()方法必須返回ActionMapping有所不同),顯示的測(cè)試結(jié)果仍然為成功。你可以在一個(gè)test方法中寫(xiě)多個(gè)測(cè)試,但個(gè)人不建議這樣使用,這會(huì)給方法的命名及程序的結(jié)構(gòu)帶來(lái)很大的困擾。此外,test方法中遇到測(cè)試失敗后便會(huì)立即返回,而不是繼續(xù)向下運(yùn)行(這和and語(yǔ)句頗有相似之處)。
7) 主要函數(shù)和作用:
setRequestPathInfo,設(shè)置request的請(qǐng)求
addRequestParameter,將參數(shù)和對(duì)應(yīng)的值加入request中
actionPerform,執(zhí)行這個(gè)請(qǐng)求
verifyForward,驗(yàn)證forward的名字是否正確
verifyForwardPath,驗(yàn)證forward的path是否正確
verifyNoActionErrors,驗(yàn)證在action執(zhí)行過(guò)程中沒(méi)有ActionError產(chǎn)生
verifyActionErrors,驗(yàn)證在action執(zhí)行過(guò)程中產(chǎn)生的ActionError集合的內(nèi)容
詳細(xì)請(qǐng)查看API DOC。
下面為一些參考網(wǎng)站:
StrutsTestCase主頁(yè):http://sourceforge.net/projects/strutstestcase/
API DOC:http://strutstestcase.sourceforge.net/api/index.html
如果需要進(jìn)一步了解Mock Objects和Cactus測(cè)試框架,可以去其官方網(wǎng)站:
Mock Objects:http://www.mockobjects.com/
Cactus:http://jakarta.apache.org/cactus/index.html