I am trying to use Struts2 JUnit Plugin (v2.2.3 w / Struts2 v2.2.3) and have encountered several problems.
As a guide, I tried using the Struts2 JUnit Plugin Tutorial . The first change I needed to make (not in the manual) was to annotate my test class:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath*:applicationContext-test.xml"})
because I was getting an error when trying to run my unit test:
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
This is different from a textbook - does anyone know why I need this?
I also had to add the following Spring Jars (I have the required Struts2 banks included in my class path):
- spring - beans -2.5.6.jar
- spring -context-2.5.6.jar
- spring -core-2.5.6.jar
- spring -test-2.5.6.jar
- spring -web-2.5.6.jar
I do not use Spring w / in my struts application, but I assume that these banks are needed to use the mock request object, etc. in a StrutsTestCase .
My testing class:
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); @Test public void testRetrieveDocumentTypesForDocumentCategory() throws UnsupportedEncodingException, ServletException { final String docCategory = "Employment";
When I execute the action, I get a NullPointerException in the request.setParameter code snippet:
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)
This is because, for some reason, request is null in StrutsTestCase . Why is this? I do what the textbook dictates!
My action class extends another class ( BaseAction ), which extends ActionSupport and implements 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; public class DocumentIndexingData extends BaseAction { private static final long serialVersionUID = 1L; private static Logger log = Logger.getLogger(DocumentIndexingData.class); private String documentCategoryDescription; private List<LabelValueBean> documentTypes; public String retrieveDocumentTypesForDocumentCategory() { List<LabelValueBean> docTypes = new ArrayList<LabelValueBean>();
struts.xml entry:
<action name="RetrieveDocumentTypesForDocumentCategory" class="com.actions.DocumentIndexingData" method="retrieveDocumentTypesForDocumentCategory"> <result type="json"> <param name="root">documentTypes</param> </result> </action>
I carefully follow the tutorial, why is request null? Thank you so much for any help!
UPDATE (My solution! Via @Alex): Now I only have the following Struts JARs included in my class path:
- struts2-junit-plugin-2.2.3.jar
- spring - beans -2.5.6.jar
- spring -context-2.5.6.jar
- spring -core-2.5.6.jar
- spring -test-2.5.6.jar
- spring -web-2.5.6.jar
Test example:
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);
}
}