Using StrutsTestCase 2.0, Strust 1.1 RC1.
I have defined an action mapping that includes two local
forwards (forward1 and forward2). My Action's execute
method currently forces the return of one of the two
forwards (forward1). However, the following
MockStrutsTestCase method passes:
setRequestPathInfo(URI);
addRequestParameter("query", "getEntity2s");
actionPerform();
verifyForward("forward1");
verifyForward("forward2");
verifyTilesForward("forward2", ".query.entity2s");
verifyNoActionErrors();
I would expect the test to fail on the second
verifyForward or, if commented out, the
verifyTilesForward. What verifyForward appears to be
doing is verifying that a local forward of that name has
been defined, *not* which one was returned. This was
working fine in v1.x (obviously without the
verifyTilesForward, which is an eagerly awaited addition!).
Logged In: YES
user_id=366284
Well, the second verifyForward() call passes because your tiles definitions
share a common base path which is used as the forwarded path, and since
verifyForward() only compares paths, it always passes.
As for the verifyTilesForward() call passing, I would need to see your tiles-
def.xml. Is the second argument the actual tiles definition being used for the
forward?
Logged In: YES
user_id=559639
So, based on your statement, verifyForward() doesn't really
buy me anything if I am using tiles. So, let's focus on
verifyTilesForward().
Yes, the second argument is the actual tiles definition. Here
is an edited version of my tiles-defs.xml (with only pertinent
definitions included):
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles
Configuration//EN"
"http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>
<!--
Master page definitions
-->
<definition name=".site.layout.main"
path="/tiles/layouts/classicLayout.jsp">
<put name="title" value="{title}" />
<put name="header" value="/tiles/header.jsp" />
<put name="menu" value=".site.menu" />
<put name="footer" value="/tiles/footer.jsp" />
<put name="body" value="{body-tile}" />
</definition>
... and others ...
<!--
Menu definitions
-->
<definition name=".site.menu"
path="/tiles/layouts/vboxLayout.jsp" >
<putList name="componentList" >
<add value=".menu.logout" />
</putList>
</definition>
<definition name=".menu.base"
path="/tiles/layouts/menuDefs.jsp" >
</definition>
<definition name=".menu.logout" extends=".menu.base" >
<putList name="items" >
<item value="Log Off" link="logoff"
classtype="org.apache.struts.tiles.beans.SimpleMenuItem" />
</putList>
</definition>
... and others ...
<!--
Page definitions, usually extensions of the Master
definition
-->
<definition name=".query.entity1s"
extends=".site.layout.main" >
<put name="title" value="Entity 1 List" />
<put name="body"
value="/pages/query/entity1s.jsp" />
</definition>
<definition name=".query.entity2s"
extends=".site.layout.main" >
<put name="title" value="Entity 2 List" />
<put name="body"
value="/pages/query/entity2s.jsp" />
</definition>
... and others ...
</tiles-definitions>
Logged In: YES
user_id=366284
I have reproduced your problem, and it is a bug, but I am afraid there is not
an easy fix for this.
The problem lies in the fact that StrutsTestCase verifies forwards by
matching paths -- there isn't any other way to do it outside of Struts, since
the forward processing mechanism is internal. That is why verifyForward()
always succeeds for tile definitions that share the same base path.
As for verifyTilesForward(), well, it's kind of in the same boat. The call you
make in your example succeeds because StrutsTestCase matches the
definition to the forward you provide -- and since the only thing else it has
to check is the forwarded path (not the forward name or tiles definition
used), it claims success.
So, it's kind of half-baked at the moment. I don't know how to collect the
information required to properly validate the tiles definitions without getting
into Struts internals.. and that would involve overloading some of the Struts
classes (thus making backwards compatibility even harder than it already is).
If you have any ideas how to accomplish this without re-architecting the
whole framework, I will gladly buy you and beer, and an expensive one at
that.
cheers.
-d.
Logged In: YES
user_id=366284
Fixing this bug is very difficult with the current Struts
(1.1) RequestProcessor architecture. The Struts team is
working on making this more flexible, which will allow me to
re-architect StrutsTestCase to be more robust.
There is no time frame for this work.
Logged In: YES
user_id=1084246
This may not be the best place to put this but we have
developed a solution to this problem. It's a bit of a
kludge and maybe there is a better way to do it, but this
will cache an action forward before it gets resolved by the
Tiles engine. So if you have a forward "success" that goes
to "MyApp.MainTile", you can call
assertResultForward("MyApp.MainTile") and verify that was
the actual tile used.
Hope it helps...
Define a class which extends MockStrutsTestCase with the
following:
protected ActionForward resultForward;
protected void setCachingRequestProcessor() throws
ServletException {
ModuleConfig mc =
RequestUtils.getModuleConfig(getRequest(),
getActionServlet().getServletContext());
RequestProcessor rp = new CachingRequestProcessor();
rp.init(getActionServlet(), mc);
getActionServlet().getServletContext().setAttribute(Globals.REQUEST_PROCESSOR_KEY,
rp);
}
public void assertResultForward(String expected) {
assertEquals(expected, this.resultForward.getPath());
}
public class CachingRequestProcessor extends RequestProcessor {
protected void processForwardConfig(HttpServletRequest
request, HttpServletResponse response, ForwardConfig
forward) throws IOException, ServletException {
resultForward = (ActionForward) forward;
super.processForwardConfig(request, response, forward);
}
Logged In: NO
verifyTilesForward does not work. Given the following action
mapping.
<action path="/mypath"
type="com.mycompany.myAction"
scope="request"
name="myForm"
validate="false">
<forward name="fwd-one"
path="TILE:definition-one">
</forward>
<forward name="fwd-two"
path="TILE:definition-two">
</forward>
<forward name="fwd-three"
path="TILE:definition-three">
</forward>
</action>
====================
In you MockStrutsTestCase.
verifyTilesForward does not work.
It does not verify what forward the ActionServlet
controller 'used' in your test.
All of these verifyTilesForward pass in my
MockStrutsTestCase.testMethod(),
yet 'myAction' can only exit with 'one' ActionForward!
verifyTilesForward("fwd-one", "TILE:definition-one" );
verifyTilesForward("fwd-two", "TILE:definition-two");
verifyTilesForward("fwd-three", "TILE:definition-three");
It does not validate or verify your test run condition, its only
verifying that those forwards found in
the struts-config.xml file are defined in the tiles.xml file.
Its useless.
Wally
Logged In: NO
verifyTilesForward does not work. Given the following action
mapping.
<action path="/mypath"
type="com.mycompany.myAction"
scope="request"
name="myForm"
validate="false">
<forward name="fwd-one"
path="TILE:definition-one">
</forward>
<forward name="fwd-two"
path="TILE:definition-two">
</forward>
<forward name="fwd-three"
path="TILE:definition-three">
</forward>
</action>
====================
In you MockStrutsTestCase.
verifyTilesForward does not work.
It does not verify what forward the ActionServlet
controller 'used' in your test.
All of these verifyTilesForward pass in my
MockStrutsTestCase.testMethod(),
yet 'myAction' can only exit with 'one' ActionForward!
verifyTilesForward("fwd-one", "TILE:definition-one" );
verifyTilesForward("fwd-two", "TILE:definition-two");
verifyTilesForward("fwd-three", "TILE:definition-three");
It does not validate or verify your test run condition, its only
verifying that those forwards found in
the struts-config.xml file are defined in the tiles.xml file.
Its useless.
Wally
Logged In: NO
Does anyone know if there is a
struts org.apache.struts.tiles.TilesPlugin Mock Test Case
runner so that you can get the names of the action forwards
in you test cases? This would be really helpful. Thanks.
Logged In: NO
The dvelopment team should add notes to the StrutsTestCase
home page (where verifyTilesForward() is discussed) and also
add a note to the javadocs, pointing out the issues with
these method calls. Doing so will save a good deal of
time/head scratching by developers out there using this
framework.