Menu

#30 verify[Tiles]Forward passes for all local forwards

RequestProcessor
open
nobody
None
5
2004-06-10
2003-05-19
No

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!).

Discussion

  • Deryl Seale

    Deryl Seale - 2003-05-20

    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?

     
  • Gareth Davies

    Gareth Davies - 2003-05-21

    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>

     
  • Deryl Seale

    Deryl Seale - 2003-05-21

    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.

     
  • Deryl Seale

    Deryl Seale - 2004-06-10
    • milestone: --> RequestProcessor
     
  • Deryl Seale

    Deryl Seale - 2004-06-10

    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.

     
  • Chris Eldredge

    Chris Eldredge - 2004-07-15

    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);
    }

     
  • Nobody/Anonymous

    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

     
  • Nobody/Anonymous

    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

     
  • Nobody/Anonymous

    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.

     
  • Nobody/Anonymous

    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.

     

Log in to post a comment.