-
Notifications
You must be signed in to change notification settings - Fork 4
FAQ
StrutsTestCase for JUnit
- Is there a discussion group for StrutsTestCase?
- Are there more detailed instructions on how to run the StrutsTestCase examples?
- Does StrutsTestCase support Tiles?
- Why does my test fail complaining about "Missing configuration resource for path /WEB-INF/struts-config.xml"?
- Why do I keep getting NoClassDefFoundErrors when I run my test case?
- Why do I keep getting LinkageError's when I run my test case?
- Why is a session value I set in one test method not available in another test method?
- How can I use the Struts transaction token support in my test cases?
- Can I access the ActionForm for my test before and after the Action is executed?
- When I use setActionForm(), why are the form attributes I set not showing up in my Action class?
- How can I test uploading a file using StrutsTestCase?
- Why does my test stop executing before the ActionForward is processed?
- Can I test multiple Actions in the same test method?
Yes, there is an active user forum hosted on the SourceForge site.
The StrutsTestCase distribution comes with several sample classes, and step-by-step instructions on how to run them. Please see the the README.txt file in the examples directory for more details.
Yes, StrutsTestCase supports Tiles. If your test are failing, make sure that your CLASSPATH
is set properly, so that StrutsTestCase can find the appropriate resource files, specifically the tiles definitions file. See the next FAQ entry for more details.
Why does my test fail complaining about "Missing configuration resource for path /WEB-INF/struts-config.xml"?
This usually occurs when your CLASSPATH
is not set properly to point to the directory that contains the WEB-INF directory. For example, if your struts-config.xml is located in the following directory:
/my/directory/WEB-INF/struts-config.xml
.. then you would set the CLASSPATH
as follows:
CLASSPATH=/my/directory
The same applies for all other resource files, like tiles definitions and the like. As an alternative, you can use the setConfigFile method to point to your configuration file, keeping in mind that you must reference the file appropriately.
Assuming that your CLASSPATH
is indeed set up properly, there are two situations where this problem might occur:
-
If the
NoClassDefFoundError
you're receiving complains about a class calledActionConfig
, then you are probably trying to use a version ofstrutstest.jar
built against Struts 1.1 in a Struts 1.0 environment. Get the version of StrutsTestCase appropriate to your test environment. -
If the
NoClassDefFoundError
you're receiving complains about eitherServletRequestWrapper
or aServletResponseWrapper
, then you are probably trying to run a version ofstrutstest.jar
that supports Servlet 2.3 in a Servlet engine that only supports the 2.2 specification. Get the version of StrutsTestCase appropriate to your test environment. -
If the
NoClassDefFoundError
you're receiving complains about Tiles classes (eg:DefinitionsUtil
orComponentDefinition
), you must include thetiles.jar
in yourCLASSPATH
. This should only an issue for Struts 1.1b1.
There are three known causes for this problem:
-
CLASSPATH
issues: If yourCLASSPATH
contains multiple XML libraries that are incompatible, you will get this error. One solution is to placesxerces.jar
at the front of yourCLASSPATH
, which ensures that a compatible set of interfaces and implementation classes are loaded. -
JUnit Swing UI TestRunner: If you are using the
swingui.TestRunner
class, you must uncheck the reload classes every run box before you run your tests. -
Ant task: If you are using the
<junit>
task, you must make sure the fork attribute is set to true before you run your tests.
StrutsTestCase follows a common JUnit practice of not saving state between unit tests. This is to avoid side effects when running many unit tests at once, each of which should remain independent of one another. If you wish to test an Action
subclass that depends on another Action
or Servlet
having set up one or more state variables, you should simulate this behavior by setting the state variables in the session object (via the getSession()
method) or the request object (via the getRequest()
method). Alternately, you can test several Action subclasses in a sequence by calling setRequestPathInfo()
and actionPerform()
for each one. For more information, please see the JUnit site.
You can use the Struts transaction token in your tests by using the addRequestParameter
method, thusly:
public void testTransactionToken() {
_addRequestParameter(Constants.TOKEN\_KEY, "test\_token");
getSession().setAttribute(Globals.TRANSACTION\_TOKEN\_KEY, "test\_token");_
setRequestPathInfo("/testToken");
actionPerform();
verifyNoActionErrors();
}
Yes, you can. Both MockStrutsTestCase
and CactusStrutsTestCase
have a setActionForm()
method for setting the ActionForm
for a given test, and a getActionForm()
method for retrieving an ActionForm
instance after the Action
is executed.
Even though you can pass an ActionForm
instance to your Action
, it does not mean you are subverting how Struts handles the form processing. In particular, if you have overridden the ActionForm.reset()
method, then you could potentially be resetting any attributes you had set in the ActionForm
instance you pass to setActionForm()
. Likewise, any request parameters you pass along that correspond to attributes in your ActionForm
instance will replace whatever you set in your test method.
This is a tricky operation to test, but at least one enterprising user has found a way to do it.
StrutsTestCase is designed to test only a single Action
class within a test method, and as such, by default does not actually process the forward, be it another action or a JSP page. This minimizes side effects that can produce spurious test results. If you are using Cactus, you can override this behavior by calling the processRequest
method so that the request is fully processed by the container.
You can also simulate calling multiple actions in a MockStrutsTestCase
test method by calling setRequestPathInfo()
and actionPerform()
multiple times within the same method. If you choose to do this, however, you should call clearRequestParameters()
to ensure that no unexpected request parameters are passed along.
Yes you can -- see the previous question.
Still scratching your head? Please post a message on the user forums.