我正在尝试为使用 Spring 3.2.2 和 Struts 2.3.12 的应用程序开发 JUnit4 测试脚本。我想我已经接近完成这项工作,但由于某种原因,当调用 executeAction 或 getActionProxy 时,我收到一个空指针错误,因为方法不存在。我没有传递正确的uri吗?还是我更想念的东西。这是一个 Maven 项目,所以我使用以下所有内容:
struts2-junit-plugin-2.3.13.jar struts 2.3.12 (core, spring plugin, dojo plugin, json plugin, sitemesh plugin) Spring 3.2.2 (core, web, context, expression, context-support, aop, aspect , 测试)
这是我的简单测试:
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";
}
}
我们所有的 context*.xml 文件都在 src/main/resources 文件夹中:
applicationContextDao.xml
applicationContextMail.xml
applicationContextSecurity.xml
applicationContextService.xml
applicationContextWeb.xml
struts.xml
这是我们的 struts 文件:
<?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)
我也尝试使用以下命令调用 executeAction:
String result = executeAction("/administration/dashboard.action");
String result = executeAction("/dashboardAction");
String result = executeAction("/administration/dashboard");
也许我需要采取一种新的方法来解决这个问题。只是以为插件会让这件事变得简单,但它看起来不像那样。
谢谢!