我正在尝试使用Struts2 JUnit插件(v2.2.3 w / Struts2 v2.2.3)并遇到了几个问题。
我尝试使用Struts2 JUnit Plugin Tutorial作为指南。我需要做的第一个更改(不在指南中)是用以下内容注释我的测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"})
因为我在尝试运行单元测试时遇到错误:
SEVERE: [56:51.239] ********** FATAL ERROR STARTING UP STRUTS-SPRING INTEGRATION **********
Looks like the Spring listener was not configured for your web app!
Nothing will work until WebApplicationContextUtils returns a valid ApplicationContext.
You might need to add the following to web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
SEVERE: [56:51.254] Dispatcher initialization failed
这与教程不同 - 有谁知道为什么我需要这样做?
我还必须添加以下Spring Jars(我的类路径中包含必要的Struts2 jar):
我没有在我的struts应用程序中使用Spring,但我认为需要使用这些jar来模拟request
中的模拟StrutsTestCase
对象。
我的测试课程:
package com.actions;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.servlet.ServletException;
import org.apache.log4j.Logger;
import org.apache.struts2.StrutsTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.beans.LabelValueBean;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"})
public class DocumentCategoryTest extends StrutsTestCase {
private static Logger log = Logger.getLogger(DocumentCategoryTest .class);
/**
* Testing RetrieveDocumentTypesForDocumentCategory
* Expecting the List<LabelValueBean> is not null
* @throws ServletException
* @throws UnsupportedEncodingException
*/
@Test
public void testRetrieveDocumentTypesForDocumentCategory() throws UnsupportedEncodingException, ServletException {
final String docCategory = "Employment";
//set parameters
request.setParameter("documentCategoryDescription", docCategory);
//execute the action
executeAction("/recipient/RetrieveDocumentTypesForDocumentCategory.action");
//retrieve the document types
@SuppressWarnings("unchecked")
List<LabelValueBean> testDocTypeList = (List<LabelValueBean>) findValueAfterExecute("documentTypes");
//make sure the document type list is not null and has at least one document type
assertNotNull(testDocTypeList);
assertTrue("At least one document type should exist for category 'Employment'", testDocTypeList.size() > 0);
//print types
log.debug("Document types for category '" + docCategory + "'");
log.debug(testDocTypeList);
}
}
当我执行操作时,我会在NullPointerException
代码上获得request.setParameter
:
java.lang.NullPointerException
at com.actions.DocumentCategoryTest.testRetrieveDocumentTypesForDocumentCategory(DocumentCategoryTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:160)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:233)
at org.springframework.test.context.junit4.SpringMethodRoadie$RunBeforesThenTestThenAfters.run(SpringMethodRoadie.java:333)
at org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:217)
at org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:197)
at org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:143)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:160)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:97)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
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)
这是因为出于某种原因,request
中StrutsTestCase
为空。为什么是这样?我正如教程所指示的那样做!
我的操作类扩展了另一个扩展BaseAction
并实现ActionSupport
的类(SessionAware
)。
package com.actions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.actions.BaseAction;
/**
* Retrieves the document types for the passed in document category
*/
public class DocumentIndexingData extends BaseAction {
private static final long serialVersionUID = 1L;
private static Logger log = Logger.getLogger(DocumentIndexingData.class);
/*=========================================================================
* FIELDS
*=========================================================================*/
/**
* The description to use to look up the document types for that category
*/
private String documentCategoryDescription;
/**
* List of document types for a category
*/
private List<LabelValueBean> documentTypes;
/*=========================================================================
* PUBLIC METHODS
*=========================================================================*/
/**
* Retrieves & sets list of document types for document category with passed in ID
*
* @return If there is an error, document type will be set to ERROR; SUCCESS is always returned by this method
*/
public String retrieveDocumentTypesForDocumentCategory() {
List<LabelValueBean> docTypes = new ArrayList<LabelValueBean>();
//retrieve document types for passed in category ID
log.debug("looking up document types for category: " + getDocumentCategoryDescription());
////////////////
//retrieve the document types for the document category here...
////////////////
this.setDocumentTypes(docTypes);
log.debug("document types found: " + getDocumentTypes());
return SUCCESS;
}
/*=========================================================================
* GETTERS/SETTERS
*=========================================================================*/
/**
* Retrieves the list of document types
*
* @return list of document types
*/
public List<LabelValueBean> getDocumentTypes() {
return documentTypes;
}
/**
* Sets the list of document types
*
* @param documentTypes
*/
public void setDocumentTypes(List<LabelValueBean> documentTypes) {
this.documentTypes = documentTypes;
}
/**
* Retrieves the document category to retrieve document types for
*
* @return the document category
*/
public String getDocumentCategoryDescription() {
return documentCategoryDescription;
}
/**
* Sets the document category to retrieve document types for
*
* @param documentCategoryDescription the document category to retrieve document types for
*/
public void setDocumentCategoryDescription(String documentCategoryDescription) {
this.documentCategoryDescription = documentCategoryDescription;
}
}
struts.xml条目:
<!-- indexing attributes action -->
<action name="RetrieveDocumentTypesForDocumentCategory" class="com.actions.DocumentIndexingData" method="retrieveDocumentTypesForDocumentCategory">
<result type="json">
<param name="root">documentTypes</param>
</result>
</action>
我非常仔细地遵循教程,为什么request
为空?非常感谢你的帮助!
更新(我的解决方案!来自@Alex): 我现在只在我的类路径中包含以下Struts JAR:
样品测试:
public class MyTest extends StrutsTestCase { @Test public void testMyAction() throws Exception { request.setParameter("aParameter", "aValue"); //create action proxy ActionProxy proxy = getActionProxy("/test/MyAction"); assertNotNull(proxy); MyAction action = (MyAction) proxy.getAction(); assertNotNull(action); //execute the action String result = proxy.execute(); //make assertions, expecting success and no error messags assertTrue("There should be no field errors: " + action.getFieldErrors(), action.getFieldErrors().size() == 0); assertTrue("There should be no action errors: " + action.getActionErrors(), action.getActionErrors().size() == 0); assertEquals("Result did not match expected value; ", Action.SUCCESS, result); } }
答案 0 :(得分:3)
我没有在我的struts应用程序中使用Spring,但我认为这些jar需要使用模拟请求对象,例如StrutsTestCase。
鉴于您在上面看到的异常消息,您的应用程序认为它使用Spring。你的类路径上有Struts2-Spring-Plugin吗?如果您没有将Spring用于IoC,则不应将其包含在类路径中。
如果你不使用Spring,你应该可以按照你没有任何弹簧罐引用的指南来测试你的行为。尝试删除所有弹簧罐和struts2-spring-plugin jar。你当然也不需要:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:applicationContext-test.xml"})
如果你不使用spring,请在你的测试类中。
同时检查struts.xml是否包含以下行:
<constant name="struts.objectFactory"
value="org.apache.struts2.spring.StrutsSpringObjectFactory"/>