Paul,
My thoughts :
* What I don't like is that we are putting too much specific logic in the
ActionTestCase and that you even have to create a MyActionTestCase for each
Action to test, which I find too heavy a process.
* I don't see the problem of init and destroy for each test case. This is
really the idea of unit tests, where each test must be independent of one
another in order not to get side effects. This is why JUnit is going at
length to ensure that each test case is loaded in it's own class loader so
that it does no interfere with another one. Also, is speed really an issue ?
* I don't think using subclasses is the best way. It is probably better to
use factory helper classes. But actually even this may not be necessary ....
Strut is using a design by composition, meaning it has very loose coupling
between classes (which is good, flexible and open to changes), meaning you
can initialize each class separately and just pass the required objects to
initialize it. It is really to initialize any object from outside the struts
framework. So unit testing it is really simple ... with Cactus (because you
still need valid request, response, session, config objects).
I am not sur of the added value of providing the following helper class for
example :
public ActionServlet createActionServlet(ServletConfig theConfig)
{
ActionServlet servlet = new ActionServlet();
servlet.init(config);
return servlet;
}
I don't personnally find it complicated and too hard to have a few init code
at the beginning of each testXXX() method (or factorized in a setUp()
method):
MyAction action = new MyAction();
action.setServlet((new ActionServlet(config)).init());
Your thoughts ?
-Vincent
----- Original Message -----
From: "Paul Holser" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, August 07, 2001 5:14 PM
Subject: Testing Struts Actions (WAS Re: Unit testing Actions)
<vincent>
* Do not define the struts initialization parameters in the web.xml file but
rather to initialize them at the beginning of your testXXX() method. The
"config" variable that you have access to has an additional method called
"setInitParameter()" that let you add parameters as if they had been defined
in web.xml.
</vincent>
thanks, i like that a lot better.
<vincent>
The idea to add a StrutsTestCase to Cactus that will make the ActionServlet
available to you in your test case. StrutsTestCase would inherit from
ServletTestCase.
</vincent>
did that. here's what i have so far. the thing i dislike about my current
strategy is that the ActionServlet is init()ed and destroy()ed for every
test method.
to save on test execution time, i'd like for the init() and destroy() to be
done once.
i know there is a test decorator in JUnit called TestSetup that's supposed
to be
for exactly this problem--but i'm not sure how to make the tests decorated
by the
TestSetup aware of the ActionServlet and Action to use. any ideas?
thx,
p
/**
* Abstract test class for testing Struts action objects.
* <p>
* Override createActionInstance() to provide this class with a concrete
* instance of Action to use. Override initializeConfig() to configure
* the ActionServlet under test with specific configuration parameters.
*/
public abstract class ActionTestCase extends ServletTestCase
{
// privatize with accessors if you prefer.
protected ActionServlet servlet;
protected Action action;
/**
* Constructs an instance.
*
* @param name the name of the test
*/
protected ActionTestCase(String name)
{
super(name);
}
/**
* Returns an instance of Action that is to be used during the tests.
*
* @return an instance of Action that is to be used during the tests
*/
protected abstract Action createActionInstance();
/**
* Populates the implicit config object with initialization parameters.
*/
protected void initializeConfig()
{
}
/**
* Sets up the test fixture.
*
* @exception Exception if a problem occurs with the setup
*/
protected void setUp() throws Exception
{
super.setUp();
this.servlet = new ActionServlet();
initializeConfig();
servlet.init(config);
this.action = createActionInstance();
action.setServlet(servlet);
}
/**
* Tears down the test fixture.
*
* @exception Exception if a problem occurs with the teardown
*/
protected void tearDown() throws Exception
{
servlet.destroy();
super.tearDown();
}
}