Struts2 Action的單元測試

對Struts2進行單元測試,以struts 2.2.1.1爲例 ,可以使用struts2發行包中的struts2-junit-plugin-2.2.1.1.jar,它裏面提供了兩個類StrutsTestCase、StrutsSpringTestCase,分別提供對純struts應用和struts+spring整合時的單元測試支持。下面分別說明。

1.StrutsTestCase

   首先準備一個純struts2工程,建立工程過程略,但有如下的類:

   Account.java,是bean

  

  1. package model; 
  2.  
  3. public class Account { 
  4.     private String userName; 
  5.     private String password; 
  6.  
  7.     public Account() { 
  8.     } 
  9.  
  10.     public Account(String userName, String password) { 
  11.         this.userName = userName; 
  12.         this.password = password; 
  13.     } 
  14.  
  15.     public String getUserName() { 
  16.         return userName; 
  17.     } 
  18.  
  19.     public void setUserName(String userName) { 
  20.         this.userName = userName; 
  21.     } 
  22.  
  23.     public String getPassword() { 
  24.         return password; 
  25.     } 
  26.  
  27.     public void setPassword(String password) { 
  28.         this.password = password; 
  29.     } 

   AccountAction.java

  

  1. package action; 
  2.  
  3. import com.opensymphony.xwork2.ActionSupport; 
  4. import model.Account; 
  5.  
  6. import java.util.logging.Logger; 
  7.  
  8. public class AccountAction extends ActionSupport{ 
  9.  
  10.     private Account accountBean; 
  11.     public String execute() throws Exception { 
  12.         return SUCCESS; 
  13.     } 
  14.  
  15.     public void validate(){ 
  16.         if (accountBean.getUserName().length()==0){ 
  17.             addFieldError("accountBean.userName","User name is required."); 
  18.         } 
  19.  
  20.         if (accountBean.getUserName().length()<5){ 
  21.             addFieldError("accountBean.userName","User name must be at least 5 characters long."); 
  22.         } 
  23.  
  24.         if (accountBean.getUserName().length()>10){ 
  25.             addFieldError("accountBean.userName","User name cannot be at more thant 10 characters long."); 
  26.         } 
  27.     } 
  28.  
  29.     public Account getAccountBean() { 
  30.         return accountBean; 
  31.     } 
  32.  
  33.     public void setAccountBean(Account accountBean) { 
  34.         this.accountBean = accountBean; 
  35.     } 

   測試類:

  TestAccountAction.java

  

  1. package ut; 
  2.  
  3. import action.AccountAction; 
  4. import com.opensymphony.xwork2.ActionProxy; 
  5. import com.opensymphony.xwork2.config.ConfigurationProvider; 
  6. import org.apache.struts2.StrutsTestCase; 
  7.  
  8. import static org.testng.AssertJUnit.*; 
  9.  
  10.  
  11. public class TestAccountAction extends StrutsTestCase { 
  12.     private AccountAction action; 
  13.     private ActionProxy proxy; 
  14.  
  15.     private void init() { 
  16.         proxy = getActionProxy("/createaccount"); //action url,可以寫擴展名".action"也可以乾脆不寫 
  17.         action = (AccountAction) proxy.getAction(); 
  18.     } 
  19.  
  20.     public void testUserNameErrorMessage() throws Exception { 
  21.         request.setParameter("accountBean.userName", "Bruc"); 
  22.         request.setParameter("accountBean.password", "test"); 
  23.  
  24.         init(); 
  25.         proxy.execute(); 
  26.  
  27.         assertTrue("Problem There were no errors present in fieldErrors but there should have been one error present"
  28.                 action.getFieldErrors().size() == 1); 
  29.         assertTrue("Problem field account.userName not present in fieldErrors but it should have been"
  30.                 action.getFieldErrors().containsKey("accountBean.userName")); 
  31.     } 
  32.  
  33.     public void testUserNameCorrect() throws Exception{ 
  34.         request.setParameter("accountBean.userName", "Bruce"); 
  35.         request.setParameter("accountBean.password", "test"); 
  36.  
  37.         init(); 
  38.         String result=proxy.execute(); 
  39.  
  40.         assertTrue("Problem There were errors present in fieldErrors but there should not have been any errors present"
  41.                 action.getFieldErrors().size()==0); 
  42.  
  43.         assertEquals("Result returned form executing the action was not success but it should have been."
  44.                 "success", result); 
  45.  
  46.     } 

   測試邏輯比較簡單,action中的validate方法會保證用戶名長度在5--9之間。

   定義struts.xml,放在類路徑的根目錄下,而非web-inf/classes下,否則會找不到,不會加載你定義的內容。

  

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2.  
  3. <!DOCTYPE struts PUBLIC 
  4.         "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
  5.         "http://struts.apache.org/dtds/struts-2.0.dtd"
  6. <struts> 
  7.     <package name="testit" namespace="/" extends="struts-default"
  8.         <action name="createaccount" class="action.AccountAction"
  9.             <result name="success">/index.jsp</result> 
  10.             <result name="input">/createaccount.jsp</result> 
  11.         </action> 
  12.     </package
  13. </struts> 

   至於action/result的定義中用到的jsp頁面,不必真實存在,保持不爲空就行,否則,action測試的時候,會說result未定義之類的錯誤,因爲此測試會模擬action真實狀態下的運行。運行,一切OK。

   正因爲會模擬真實狀態下的運行,所以攔截器也會正常被觸發,下面再定義一個攔截器測試一下:

   MyInterceptor.java

  

  1. package interceptor; 
  2.  
  3. import com.opensymphony.xwork2.ActionInvocation; 
  4. import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 
  5.  
  6. public class MyInterceptor extends AbstractInterceptor{ 
  7.  
  8.     public String intercept(ActionInvocation actionInvocation) throws Exception { 
  9.         System.out.println("before processing"); 
  10.        String rst= actionInvocation.invoke(); 
  11.         System.out.println("bye bye "+actionInvocation.getProxy().getMethod()); 
  12.         return rst; 
  13.     } 

  

   修改一下struts.xml,加入攔截器的定義:

   <package name="testit" namespace="/" extends="struts-default">
       <interceptors>
            <interceptor name="testInterceptor" class="interceptor.MyInterceptor"/>
        </interceptors>
        <action name="createaccount" class="action.AccountAction">
            <result name="success">/index.jsp</result>
            <result name="input">/createaccount.jsp</result>
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="testInterceptor"/>
        </action>
    </package>

   運行,控制檯會輸出:

   before processing

   bye bye execute

    使用的jar包如下圖:

  

   都是struts發行包提供的,其它不相關的jar不要加,尤其是以plugin.jar結尾的文件,更不要加struts2-spring-plugin-2.2.1.1.jar,加了會加載相關的東西,但這裏卻提供不了,導致測試無法運行。實際spring-beans-2.5.6.jar和spring-context-2.5.6.jar也不是必須的,但加了也無所謂,在StrutsSpringTestCase是需要的。另外,web.xml不需要配置,根本不會去這裏找配置信息。

  

2.StrutsSpringTestCase

  這個和前面的過程類似,需要的類分別如下。

  MathAction.java

 

  1. package action; 
  2.  
  3. import com.opensymphony.xwork2.ActionContext; 
  4. import com.opensymphony.xwork2.ActionSupport; 
  5. import org.apache.struts2.ServletActionContext; 
  6. import service.MathService; 
  7.  
  8. public class MathAction extends ActionSupport{ 
  9.     private MathService service; 
  10.  
  11.     public String execute() throws Exception { 
  12.         ServletActionContext.getRequest().setAttribute("add.result",service.add(1,2)); 
  13.         return SUCCESS; 
  14.     } 
  15.  
  16.     public MathService getService() { 
  17.         return service; 
  18.     } 
  19.  
  20.     public void setService(MathService service) { 
  21.         this.service = service; 
  22.     } 

  MathService.java

 

  1. package service; 
  2.  
  3. public class MathService { 
  4.     public int add(int a,int b){ 
  5.         return a+b; 
  6.     } 

  測試類TestMathAction,測試一下MathService.add是否能正確地返回兩個數相加的值。

 

  1. import action.MathAction; 
  2. import com.opensymphony.xwork2.ActionProxy; 
  3. import org.apache.struts2.StrutsSpringTestCase; 
  4.  
  5. public class TestMathAction  extends StrutsSpringTestCase{ 
  6.     private MathAction action; 
  7.     private ActionProxy proxy; 
  8.  
  9.     protected String getContextLocations() { 
  10.         return "spring/applicationContext.xml"
  11.     } 
  12.  
  13.     private void init(){ 
  14.         proxy=getActionProxy("/add"); 
  15.         action=(MathAction)proxy.getAction(); 
  16.     } 
  17.     public void testAdd() throws Exception{ 
  18.         init(); 
  19.         proxy.execute(); 
  20.         assertEquals(request.getAttribute("add.result"),3); 
  21.     } 

  這裏有一個小trick,默認情況下,applicationContext.xml也要放在classpath的根目錄下,但如果項目需要不放在那裏,就要覆蓋getContextLocations方法返回其class path,開頭可以有也可以沒有“/”,這裏我放在包spring下,所以就返回spring/applicationContext.xml,至於struts和spring整合的配置就不用寫了,想必大家都會。需要的jar在上面的基礎上,加入struts2-spring-plugin-2.2.1.1.jar就行了,對了,兩種測試都需要jsp-api.jarservlet-api.jar,去tomcat裏copy一份即可,junit.jar也是需要的(廢話?!)

 

發佈了5 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章