ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Unit Test Your Struts Application
Pages: 1, 2, 3, 4, 5

How to Write the Test Case



Here are the key points of how to write the test case.

  • Each test case should extend from StrutsServletTestCase.

  • Define a public ActionForm prepareFormXXX(ActionMapping) method if you want to prepare the ActionForm instance.

  • Define a public Action prepareActionXXX(ActionMapping) method if you want to prepare the Action instance.

  • Define a public ActionResult endActionXXX() method if you want to verify the mock object and/or introduce the next join point. The return value of this method is an ActionResult object that contains a String attribute. In a real Struts application environment, it is quite possible that the forward of an action is also an action instead of a JSP file. In this circumstance, the return value of this method is used to specify the next join point position. For example, if the return ActionResult contains the string YYY, the Struts framework will try to call prepareFormYYY() and prepareActionYYY() before calling the next Action, and call endActionYYY() after the Action execution. The next example gives you a more complicated scenario and test case. There are two predefined ActionResult instances: TERMINATE and CONTINUE. TERMINATE simply terminates the process of Struts and return the control flow. CONTINUE or null will continue the Struts operation as usual.

A More Complicated Example

Change the Struts configuration file to make the Action forward more complicated.

//struts-config.xml

    ...
    <action  
              path="/strutsTest"
              type="unittest.struts.SimpleAction"
              name="simpleForm"
              scope="request">
      <forward 
              name="succeed"              
        path="/anotherTest.do"/>
    </action>

    <action    
              path="/anotherTest"
              type="unittest.struts.AnotherAction">
      <forward 
              name="succeed"              
              path="/result.jsp"/>
    </action>  
    ...

</struts-config>

Introduce an extra Action into the scenario:

//AnotherAction.java
package unittest.struts;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import unittest.simple.ExternalInf;

public class AnotherAction extends Action {
   public ActionForward execute(
                    ActionMapping mapping, 
                    ActionForm form,
                    HttpServletRequest request, 
                    HttpServletResponse response)
                    throws Exception {
      String name = (String)request.
                            getAttribute("name");
      ExternalInf inf = getExternalInf();
      request.setAttribute("name", name + 
                          inf.doSomeExtThing(1));
      return mapping.findForward("succeed");
   }

   protected ExternalInf getExternalInf() {
      ExternalInf inf = null;
      //do some operation to get the 
      //external interface
      //Use JNDI operation or something else
      return inf;
   }
} 

Write a new test case to test this complicated scenario:

//AnotherStrutsTest.java
package unittest.struts;

import javax.servlet.RequestDispatcher;

import org.apache.cactus.WebRequest;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.easymock.MockControl;
import org.jingle.unittest.struts.*;

import unittest.simple.ExternalInf;

import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebResponse;

public class AnotherStrutsTest 
                  extends StrutsServletTestCase {
   ...
   //Same as what in SimpleStrutsTest

   //Prepare the AnotherAction
   public Action prepareActionAnotherAction(
                         ActionMapping mapping) {
      //define the behavior of mock object
      controller.reset();
      inf.doSomeExtThing(1);
      controller.setReturnValue("Little");
      controller.replay();
      
      //Use override technology to bridge the 
      //mock object to the class to be tested
      AnotherAction action=new AnotherAction() {
         protected ExternalInf getExternalInf() {
            return inf;
         }
      };
      return action;
   }
   ...

   //verify the mock object after the execution 
   //of action
   public ActionResult 
                    endActionStrutsTestAction() {
      controller.verify();
      //Introduce next join point "AnotherAction"
      return new ActionResult("AnotherAction");
   }    

   //compare the result html documents
   public void endStrutsTestAction(
                          WebResponse response) {
      try {
         WebForm form = response.getForms()[0];
         assertEquals(
                 "DennisGreatLittle", 
                 form.getParameterValue("name"));
      } catch (Exception e) {
         fail("Unexpected exception: " + e);
      }
   }
} 

Pages: 1, 2, 3, 4, 5

Next Pagearrow