我正在爲我們的應用程序開發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");
也許我需要採取一種新的方法來做到這一點。只是認爲插件會讓這個容易,但它看起來並不像那樣。
謝謝!
測試的executeAction調用失敗,所以它不會繼續執行containsErrors()我剛剛放進去的東西返回來驗證我的測試工作。我想這是一種整合和單元測試。我們需要驗證對動作的調用是否可以正常使用spring和struts加載,不知道我們可以做到這一點。 – 2013-05-02 19:27:39