隨筆-26  評論-13  文章-46  trackbacks-0
          利用StrutsTestCase測試Struts應(yīng)用程序




          作者:葉楓(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]
          關(guān)鍵字:Struts StrutsTestCase


          一、Struts測試概述
          ??
          ??一個具有良好系統(tǒng)架構(gòu)的J2EE應(yīng)用程序至少有三層組成,即表現(xiàn)層,商業(yè)層和系統(tǒng)
          集成層(包括數(shù)據(jù)存取以及和其他系統(tǒng)集成),目前,Struts是應(yīng)用比較廣泛,實現(xiàn)MVC2模式應(yīng)用于表現(xiàn)層的一種技術(shù). 在這里面,Struts Action主要用來完成一些簡單的數(shù)據(jù)校驗,轉(zhuǎn)換,以及流程轉(zhuǎn)發(fā)控制(注意:這里流程不是業(yè)務(wù)規(guī)則). 因此在對整個應(yīng)用程序進行測試時,我們同時也要測試Struts Action.

          ??但是,測試Struts Action相對測試簡單的JavaBean是比較困難,因為Struts是運行在Web服務(wù)器中, 因此要測試Struts Action就必須發(fā)布應(yīng)用程序然后才能測試. 我們想象一下,對于一個擁有上千個JSP page和數(shù)百甚至數(shù)千Java Classes的大規(guī)模應(yīng)用程序,要把他們發(fā)布到諸如Weblogic之類的應(yīng)用服務(wù)器再測試,需要多少的時間和硬件資源? 所以這種模式的測試是非常費時費力的.

          ??所以,如果有一種辦法能夠不用發(fā)布應(yīng)用程序,不需要Web服務(wù)器就能象測試普通Java Class一樣測試Struts Action,那就能極大地加強Struts的可測試性能,使應(yīng)用程序測試更為容易,簡單快速. 現(xiàn)在這個工具來了,這就是StrutsTestCase.


          二、StrutsTestCase 概述

          ??StrutsTestCase 是一個功能強大且容易使用的Struts Action開源測試工具,
          它本身就是在大名鼎鼎的JUnit基礎(chǔ)上發(fā)展起來的。因此通過和JUnit結(jié)合
          使用能極大加強應(yīng)用程序的測試并加快應(yīng)用程序的開發(fā).
          ??
          ??StrutsTestCase提供了兩者測試方式,模仿方式和容器測試方式. 所謂模仿方式就是有StrutsTestCase本身來模擬Web服務(wù)器. 而容器測試方式則需要Web服務(wù)器. 本文要討論的是前者,原因很簡單,不需要Web服務(wù)器就能象測試普通的Java Class一樣測試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本身就是從JUnit繼承的,所以你還需要下載JUnit3.8.1.

          ??在本文中,我們用一個簡單的例子來做測試. 假設(shè)我們有一張表Hotline(country varchar2(50),pno varchar2(50)),
          我們要做的是根據(jù)輸入條件從這張表檢索相應(yīng)的記錄.檢索條件是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{
          ???????? //調(diào)用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都是從MockStrutsTestCase繼承下來的.
          ????下面我們就創(chuàng)建一個最簡單的測試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就可以直接運行.不需要發(fā)布你的程序,不需要任何的Web服務(wù)器支持,就可以測試Struts Action,這就是StrutsTestCase帶來的好處.下面簡單地介紹一下它是怎么工作的.

          ????在上面的例子中,我們調(diào)用setRequestPathInfo()告訴StrutsTestCase我們要模擬JSP調(diào)用SearchHotline.do這個Action,并且調(diào)用addRequestParameter()增加了一個參數(shù)country.最后調(diào)用actionPerform()運行.

          看到這里,大家發(fā)現(xiàn)一個問題沒有? 在上面Action的源代碼里我們是通過

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


          也就是ActionForm來取得輸入的參數(shù)值,可我們在testSearchHotline()方法里并沒有設(shè)置ActionForm?

          那么它是怎么出來的呢? 其實大家如果熟悉Struts的運行流程的話就知道,JSP接受用戶的輸入并發(fā)請求時
          都是類似這樣的http://hostname/servletName?param1=value1&param2=value2. 只是Struts接受到這些
          參數(shù)后再根據(jù)Struts Config里的Action和ActionForm的映射把他們轉(zhuǎn)為ActionForm后傳給Action的.

          ?? 在上面的例子,我們只是簡單地運行了Action,那么Action是否正確執(zhí)行以及返回的結(jié)果是不是我們想要的呢?

          我們繼續(xù)完善一下testSearchHotline()這個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是否正確執(zhí)行.
          ?? verifyNoActionErrors() -- 判斷Action里沒有任何的Action;
          ?? verifyForward("hotlineList") -- 判斷Action確實轉(zhuǎn)發(fā)到hotlineList;??????
          ?? assertNotNull(request.getAttribute("hotlineList")) -- 判斷Action確實返回了hotlineList并且不為空

          到這里,我們已經(jīng)基本上討論完了StrutsTestCase的核心部分. 從頭到尾,我們沒有發(fā)布應(yīng)用程序,也不需要Web服務(wù)器,對我們來講,Struts Action就象普通的Java Class一樣容易調(diào)試測試.這就是StrutsTestCase給我們帶來的方便.

          五、深入StrutsTestCase

          ??除了以上我們用到的幾個斷定和校驗方法外,StrutsTestCase還提供了其他幾個方法便于我們測試Struts Action. 下面我一一講述,具體的大家可以參考文檔.

          verifyActionErrors/Messages --??校驗ActionActionServlet controller 是否發(fā)送了ActionError或ActionMessage.?? 參數(shù)為ActionError/Message Key
          verifyNoActionErrors/Messages --校驗ActionActionServlet controller 沒有發(fā)送ActionError或ActionMessage
          VerifyForward -- 校驗Action是否正確轉(zhuǎn)發(fā)到指定的ActionForward.
          VerifyForwardPath -- 校驗Action是否正確轉(zhuǎn)發(fā)到指定的URL
          verifyInputForward -- 校驗Action是否轉(zhuǎn)發(fā)到Action Mapping里的input屬性
          verifyTilesForward/verifyInputTilesForward--和以上類似,應(yīng)用程序使用到tiles時用的

          六、關(guān)于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,
          ??那么必須調(diào)用setConfigFile()設(shè)置你的struts config文件
          ??

          七、結(jié)束語
          ??J2EE應(yīng)用程序的測試在開發(fā)過程中占有相當重要的位置,利用StrutsTestCase能極大方便你測試基于Struts的應(yīng)用程序.
          posted on 2006-04-26 13:47 似水流年 閱讀(210) 評論(0)  編輯  收藏 所屬分類: Struts

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 荆门市| 肇源县| 汪清县| 凯里市| 河池市| 日土县| 平利县| 昌都县| 增城市| 城市| 杭州市| 梅州市| 隆安县| 云和县| 钟祥市| 玛曲县| 高尔夫| 乌鲁木齐县| 景东| 西藏| 呈贡县| 福州市| 阿拉善左旗| 贵州省| 望谟县| 华容县| 丹巴县| 闸北区| 河北省| 固镇县| 平度市| 大同县| 溧水县| 竹山县| 长垣县| 邵武市| 新乡县| 罗田县| 安义县| 济阳县| 鸡西市|