在測試驅動開發(Test-Driven Development TDD)的理念下,單元測試技術顯得至關重要。
在基于Struts項目中,會有大量封裝業務流程的Action類,對它們的測試是必要的。但由于Struts1中Action與Servlet容器的耦合程度較深,對Action的測試比較困難(Action的execute方法需要HttpServletRequest和HttpServletResponse對象才能調用)顯然不適合大規模,迭代式的測試。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 對于在測試過程中,對于某些不易構建的對象(如HTTPServletRequest對象),可以創建一個虛擬的對象以便進行測試,這樣的對象稱之為mock對象,mock這個詞的含義是“模仿,仿制品”。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> StrutTest組件作為Junit框架的擴展可以為我們創建出用于測試Strut Action的mock對象。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 可以從其官方網站下載該組件 http://strutstestcase.sourceforge.net 。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 下面的Demo用于演示使用strutstest組件對Struts Action進行基于Junit的單元測試。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 以下是一個很簡單的Action及其配置文件,是我們的測試目標,這個Action實現了一個簡單的登登~~登錄功能(這樣的Demo太多了是吧,我盡量保證是最后一次登錄
)
?<wbr></wbr>
?<wbr></wbr>public class LogonAction extends Action {
?<wbr></wbr>?<wbr></wbr> public ActionForward execute(ActionMapping mapping, ActionForm form,
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> HttpServletRequest request, HttpServletResponse response)
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> throws Exception {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> LogonForm f = (LogonForm) form;
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> String username = f.getUsername();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> String password = f.getPassword();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> if ("whatisjava".equals(username) && "java".equals(password)) {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> HttpSession session = request.getSession();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> session.setAttribute("username", username);
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> return mapping.findForward("success");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> } else {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> ActionMessages messages = new ActionMessages();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>messages.add("fail.logon", new ActionMessage("msg.fail.logon"));
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> saveMessages(request, messages);
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> return mapping.findForward("failed");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> ?<wbr></wbr>?<wbr></wbr> }
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>}
}
?<wbr></wbr>
<action path="/logon" type="action.LogonAction" name="logonForm">
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr><forward name="success" path="/jsp/success.jsp"/>
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr><forward name="failed" path="/jsp/logon_form.jsp"/>
?<wbr></wbr></action>
?<wbr></wbr>
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 我們要測試的目標是,登錄成功或失敗后是否返回合適的forward對象,而且登錄成功后session對象中是否存有用戶名,而登錄失敗后request中是存有相應的ActionMessage對象。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 首先將下載到的StrutsTest發行包中的strutstest-2.1.4.jar文件復制到應用的/WEB-INF/lib目錄下,另外該組件的運行還需要apache的commons-collections-2.1.jar組件。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 編寫單元測試類TestLogonAction如下,注意:該測試類要繼承StrutsTest的MockStrutsTestCase類。根據測試用例編寫測試方法:testSuccess用于測試登錄成功的情況而testFailed用于測試登錄失敗的情形。 MockStrutsTestCase幾個重要的API需要了解一下:
- setContextDirectory(File) 用于指定web應用的根目錄,StrutsTest在工作的時候需要讀取Struts配置文件struts-config.xml,StrutsTest會在指定的根目錄下的WEB-INF目錄下查找struts-config.xml文件。注意,如果使用MyEclipse,它創建Web項目時會默認在工程目錄下建立一個名為WebRoot的子目錄作為應用的根目錄,這樣就需要運行setContextDirectory(new File("WebRoot"))方法。
- addRequestParameter(String, String) 該方法用于向StrutsTest提供的mock對象中添加請求參數對以模擬用戶提交的請求信息,這里使用該方法添加username和password的請求參數對用于模擬用戶的登錄表單提交。
- setRequestPathInfo(String) 該方法用于設定要訪問的Action,String類型的參數為要訪問的Action在Struts配置文件中對應的path屬性值。
- getSession() 用于獲取StrutsTest創建的用于模擬HttpSesssion對象的mock對象。
- getRequest() 用于獲取StrutsTest創建的用于模擬HttpServletRequest對象的mock對象。
- verifyForward(String) 斷言方法,表示Action返回的特定的Forward對象,其中字符串參數表示應該返回的Forward對象在Struts配置文件中對于的forward元素的name屬性。例如verifyForward("success"); 如果返回的ActionForward對象對應的name不是success,則斷言失敗。 verifyForwardPath(String)類似于verifyForward方法,只不過String參數表示的是Action返回的forward對象所對應的URI地址。
- verifyActionMessages(String[]) 斷言方法,表示request中有一系列特定property名稱的ActionMessage對象。
- actionPerform() 執行測試過程。
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> 測試類代碼如下:?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>
public class TestLogonAction extends MockStrutsTestCase {
?<wbr></wbr>?<wbr></wbr> protected void setUp() throws Exception {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> super.setUp();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> setContextDirectory(new File("WebRoot"));
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> setRequestPathInfo("/logon");
?<wbr></wbr> ?<wbr></wbr>}
?<wbr></wbr>?<wbr></wbr> public void testSuccess() throws Exception {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> addRequestParameter("username", "whatisjava");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> addRequestParameter("password", "java");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> actionPerform();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> verifyForward("success");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> ?<wbr></wbr>verifyForwardPath("/jsp/success.jsp");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> ?<wbr></wbr>assertEquals("whatisjava", getSession().getAttribute("username"));
?<wbr></wbr>?<wbr></wbr> }
?<wbr></wbr>?<wbr></wbr> public void testFailed() {
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> addRequestParameter("username", "whatisjava");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> addRequestParameter("password", "avaj");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> actionPerform();
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> verifyForward("failed");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> verifyForwardPath("/jsp/logon_form.jsp");
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> verifyActionMessages(new String[]{"msg.fail.logon"});
?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr>?<wbr></wbr> assertNull(getSession().getAttribute("username"));
?<wbr></wbr>?<wbr></wbr> }
}
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
