2013-05-02 51 views
1

我正在爲我們的應用程序開發JUnit4測試腳本,該腳本使用Spring 3.2.2和Struts 2.3.12。我想我接近得到這個工作,但由於某種原因,當調用executeAction或getActionProxy被調用時,我得到一個空指針錯誤,因爲方法不存在。我沒有通過正確的烏里?還是更多我缺少的東西。這是一個maven項目,所以我使用以下所有內容:當用Struts 2.3.12和Spring運行Junit4時的空指針3.1.1和Spring 3.1.1

struts2-junit-plugin-2.3.13.jar struts 2.3.12(core,spring plugin,dojo插件,json插件,sitemesh插件) 春3.2.2(核心,網絡,背景,表情,背景支持,AOP方面,測試)

這是我簡單的測試:

package com.execupharm.lms.web.action.administration.test; 

import static org.junit.Assert.assertFalse; 

import org.apache.struts2.StrutsSpringJUnit4TestCase; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

import com.execupharm.lms.web.action.administration.DashboardAction; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({ "classpath:applicationContextWeb.xml", 
"classpath:applicationContextSecurity.xml", 
         "classpath:applicationContextService.xml", 
         "classpath:applicationContextDao.xml", 
         "classpath:applicationContextMail.xml" }) 
public class DashboardActionTest extends StrutsSpringJUnit4TestCase<DashboardAction> { 
    @Test 
    public void executeTest() throws Exception { 
     String result = executeAction("/administration/dashboard.action"); 
     System.out.println("result = " + result); 
     //DashboardAction action = getAction(); 
     assertFalse(containsErrors()); 
    } 

    /** 
    * Override this method to return a comma separated list of paths to a 
     configuration 
    * file. 
    * <p>The default implementation simply returns <code>null</code>. 
    * 
    * @return a comma separated list of config locations 
    */ 
    @Override 
    protected String getConfigPath() { 
     return "classpath:struts.xml"; 
    } 
} 

我們所有的上下文的* .xml文件是在src/main/resources文件夾中:

applicationContextDao.xml 
applicationContextMail.xml 
applicationContextSecurity.xml 
applicationContextService.xml 
applicationContextWeb.xml 
struts.xml 

這是我們的支柱文件:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
    "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
    <!-- Constants --> 
     <constant name="struts.locale" value="en"/> 
     <constant name="struts.devMode" value="false" /> 
     <constant name="struts.i18n.encoding" value="UTF-8" /> 
     <constant name="struts.action.extension" value="action" /> 
     <constant name="struts.objectFactory" value="spring" /> 
     <constant name="struts.objectFactory.spring.autoWire" value="name" /> 
     <constant name="struts.objectFactory.spring.useClassCache" value="true" /> 
     <constant name="struts.custom.i18n.resources" value="app_resources" /> 
     <constant name="struts.multipart.maxSize" value="12000000" /> 
     <constant name="struts.multipart.saveDir" value="/LMS_Media" /> 
     <constant name="struts.multipart.parser" value="jakarta" /> 
     <constant name="struts.codebehind.pathPrefix" value="/WEB-INF/jsp/" /> 
     <constant name="struts.enable.SlashesInActionNames" value="true" /> 
     <constant name="struts.url.http.port" value="80" /> 
     <constant name="struts.date.format" value="MM/dd/yyyy" /> 

    <!-- Configuration for the default package. --> 
    <package name="default" extends="struts-default,json-default" namespace="/"> 

     <interceptors> 
      <interceptor name="permissionsInterceptor" 
       class="com.execupharm.lms.web.interceptor.PermissionsInterceptor" /> 
      <interceptor name="employeeIdResolverInterceptor" 
       class="com.execupharm.lms.web.interceptor.EmployeeIdResolverInterceptor" /> 
      <!-- 
       Copied from struts-default.xml and changed validation exclude 
       methods 
      --> 
      <interceptor-stack name="defaultStack"> 
       <interceptor-ref name="exception"> 
        <param name="logEnabled">true</param> 
        <param name="logLevel">ERROR</param> 
        <param name="logCategory">com.execupharm.lms</param> 
       </interceptor-ref> 
       <interceptor-ref name="alias" /> 
       <interceptor-ref name="servletConfig" /> 
       <interceptor-ref name="params"> 
        <!-- 
         Excludes the jQuery no-cache _ parameter and our own search. 
         params 
        --> 
        <param name="excludeParams"> 
         _,search\..* 
        </param> 
       </interceptor-ref> 
       <interceptor-ref name="prepare" /> 
       <interceptor-ref name="i18n" /> 
       <interceptor-ref name="chain" /> 
       <interceptor-ref name="debugging" /> 
       <interceptor-ref name="profiling" /> 
       <interceptor-ref name="scopedModelDriven" /> 
       <interceptor-ref name="modelDriven" /> 
       <interceptor-ref name="fileUpload" /> 
       <interceptor-ref name="checkbox" /> 
       <interceptor-ref name="staticParams" /> 
       <interceptor-ref name="params"> 
        <param name="excludeParams">dojo\..*</param> 
       </interceptor-ref> 
       <interceptor-ref name="conversionError" /> 
       <interceptor-ref name="validation"> 
        <param name="excludeMethods">cancel,execute,delete,edit,list</param> 
       </interceptor-ref> 
       <interceptor-ref name="workflow"> 
        <param name="excludeMethods">input,back,cancel,browse,execute</param> 
       </interceptor-ref> 
       <interceptor-ref name="permissionsInterceptor" /> 
       <interceptor-ref name="employeeIdResolverInterceptor" /> 
      </interceptor-stack> 
     </interceptors> 

     <global-results> 
      <result name="error">/error.jsp</result> 
      <result name="forbidden">/forbidden.jsp</result> 
     </global-results> 

     <action name="login" class="loginAction"> 
      <result name="success">/login.jsp</result> 
     </action> 

     <action name="logout" class="logoutAction"> 
      <result name="success" type="redirect">/login.action</result> 
     </action> 
    </package> 
    <!-- End Default Package --> 

    <!-- Administration --> 

    <package name="administration" extends="default" namespace="/administration"> 
     <action name="dashboard" class="dashboardAction"> 
       <result name="success">/WEB-INF/jsp/administration/dashboard.jsp 
       </result> 
      </action> 

      <action name="addTraining" class="addTrainingAction"> 
       <result name="success">/WEB-INF/jsp/training/addTraining.jsp 
       </result> 
      </action> 

      <action name="searchSOPs" class="searchSOPsAction"> 
       <result name="success">/WEB-INF/jsp/training/searchSOPs.jsp 
       </result> 
      </action> 

      <action name="searchTests" class="searchTestsAction"> 
       <result name="success">/WEB-INF/jsp/training/searchTests.jsp 
       </result> 
      </action> 

       <action name="viewTraining" class="viewTrainingAction"> 
       <result name="success">/WEB-INF/jsp/training/viewTraining.jsp 
       </result> 
      </action> 

      <action name="viewSOP" class="viewSOPAction"> 
       <result name="success">/WEB-INF/jsp/training/viewSOP.jsp 
       </result> 
      </action> 

      <action name="viewSOPSave" class="viewSOPAction" method="save"> 
       <result name="input">/WEB-INF/jsp/training/viewSOP.jsp 
       </result> 
       <result name="success" type="redirect">dashboard.action 
       </result> 
      </action>  

      <action name="viewTest" class="viewTestAction"> 
       <result name="success">/WEB-INF/jsp/training/viewTest.jsp 
       </result> 
      </action> 

       <action name="viewMedia" class="viewMediaAction"> 
       <result name="success">/WEB-INF/jsp/training/viewMedia.jsp 
       </result> 
      </action> 

    </package> 

    <package name="training" extends="default" namespace="/training">    

    </package> 

</struts> 

applicationContextWeb.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-3.1.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 

    <bean id="loginAction" class="com.execupharm.lms.web.action.LoginAction" scope="prototype"/> 
    <bean id="logoutAction" class="com.execupharm.lms.web.action.LogoutAction" scope="prototype"/> 

    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> 
    <context:annotation-config /> 

    <bean id="dashboardAction" class="com.execupharm.lms.web.action.administration.DashboardAction" scope="prototype" /> 

    <bean id="addTrainingAction" class="com.execupharm.lms.web.action.training.AddTrainingAction" scope="prototype" /> 

    <bean id="searchSOPsAction" class="com.execupharm.lms.web.action.training.SearchSOPsAction" scope="prototype" /> 
    <bean id="searchTestsAction" class="com.execupharm.lms.web.action.training.SearchTestsAction" scope="prototype" /> 
    <bean id="viewTrainingAction" class="com.execupharm.lms.web.action.training.ViewTrainingAction" scope="prototype" /> 
    <bean id="viewSOPAction" class="com.execupharm.lms.web.action.training.ViewSOPAction" scope="prototype" /> 
    <bean id="viewTestAction" class="com.execupharm.lms.web.action.training.ViewTestAction" scope="prototype" /> 
    <bean id="viewMediaAction" class="com.execupharm.lms.web.action.training.ViewMediaAction" scope="prototype" /> 

</beans> 

這是我們得到的錯誤,我們得到:

java.lang.NullPointerException 
    at org.apache.struts2.impl.StrutsActionProxy.getErrorMessage(StrutsActionProxy.java:69) 
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185) 
    at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63) 
    at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39) 
    at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58) 
    at org.apache.struts2.StrutsJUnit4TestCase.getActionProxy(StrutsJUnit4TestCase.java:149) 
    at com.execupharm.lms.web.action.administration.test.DashboardActionTest.executeTest(DashboardActionTest.java:24) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

我已經打過電話了執行以下操作:

String result = executeAction("/administration/dashboard.action"); 
String result = executeAction("/dashboardAction"); 
String result = executeAction("/administration/dashboard"); 

也許我需要採取一種新的方法來做到這一點。只是認爲插件會讓這個容易,但它看起來並不像那樣。

謝謝!

回答

1

如果您涉及到Struts和Spring,我不會稱之爲單元測試。這是一個綜合測試。

在我看來,containsErrors()方法在assert中沒有檢查錯誤是否爲空。

+0

測試的executeAction調用失敗,所以它不會繼續執行containsErrors()我剛剛放進去的東西返回來驗證我的測試工作。我想這是一種整合和單元測試。我們需要驗證對動作的調用是否可以正常使用spring和struts加載,不知道我們可以做到這一點。 – 2013-05-02 19:27:39

0

找出問題所在。事實證明,在測試中覆蓋struts.xml文件是由於某種原因導致的錯誤,只有struts-default被使用。一旦我刪除了該行(因爲它已經在類路徑中,不需要覆蓋它),Junit測試工作。