Unit Test Your Struts Application

Unit Test Your Struts Application

StrutsUT AspectJ Solution

Compared to the traditional solution, the AspectJ solution is more transparent to the test case writer. There's no extension to the Struts central controller and test case base class, just an added aspect: StrutsTestCaseAspect.

Refer to the References section at the end of the article to learn more about AspectJ.

// StrutsTestCaseAspect.java

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;



import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

import org.apache.cactus.ServletTestCase;

import org.apache.struts.action.Action;

import org.jingle.unittest.struts.util.*;

import org.jingle.unittest.struts.*;



public aspect StrutsTestCaseAspect {

    

  pointcut setup(ServletTestCase testcase) 

  : execution(protected void org.apache.cactus.ServletTestCase+.setUp())

    && this(testcase);

    

  pointcut teardown(ServletTestCase testcase) 

  : execution(protected void org.apache.cactus.ServletTestCase+.tearDown())

    && this(testcase);

    

  pointcut actionExecute(ActionMapping mapping, ActionForm form, 

           HttpServletRequest request, HttpServletResponse response) 

  : execution(public ActionForward org.apache.struts.action.Action+.execute

       (ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse))

    && args(mapping, form, request, response);

    

  after(ServletTestCase testcase) 

  : setup(testcase) 

    && (!cflowbelow(setup(ServletTestCase))) 

    && (!within(org.jingle.unittest.struts.StrutsServletTestCase+)) {

       ... //add extra info about the test point and test case instance

  }

    

  before(ServletTestCase testcase)

  : teardown(testcase) 

    && (!cflowbelow(teardown(ServletTestCase))) 

    && (!within(org.jingle.unittest.struts.StrutsServletTestCase+)) {

       ... //clear the extra info

  }

    

  ActionForward around(ActionMapping mapping, 

                       ActionForm form, 

                       HttpServletRequest request, 

                       HttpServletResponse response) throws Exception

  : actionExecute(mapping, form, request, response) 

    && (!cflowbelow(actionExecute(ActionMapping, 

                                  ActionForm, 

                                  HttpServletRequest, 

                                  HttpServletResponse))) 

    && if (request.getAttribute(

         StrutsTestCaseConstants.WRAPPER_ACTION_ATTR_NAME) == null) {

      ... //introduce the join points before and after the execution()

          //in Action

  }

}

There are three pointcuts defined in the aspect: setup, teardown, and actionExecute.

  • The setup pointcut will be captured after the setUp() method in the test case executes, to save extra information about the test point and test case instance.

  • The teardown pointcut will be captured before tearDown()'s method execution in the test case, to clear any extra information.

  • The actionExecute pointcut will be captured during the execute() method's execution in the Action class to introduce join points.

A Simple Test Case

The AspectsimpleStrutsTest is almost the same as SimpleStrutsTest used in the traditional solution, except that it extends the ServletTestCase defined in the Cactus framework, instead of StrutsServletTestCase (provided by StrutsUT).

// AspectSimpleStrutsTest.java

package unittest.struts;



...

public class AspectSimpleStrutsTest extends ServletTestCase {

    ... //same as SimpleStrutsTest

}

How to Write the Test Case

Writing test cases in the AspectJ solution is similar to how you write them in the traditional solution, except for the first rule: each test case should extend from the ServletTestCase defined in Cactus framework.

The more complicated test case in the AspectJ solution, AspectAnotherStrutsTest, is also available in the sample code package.

How to Install StrutsUT

Here are the steps to install StrutsUT:

  • Prepare the web container. It can be Tomcat, JBoss, or another web container product.

  • Install the Struts framework into your web container.

  • Install Cactus into your web container.

  • Copy StrutsUT.jar into your web application lib directory: %CONTEXT_PATH%/WEB-INF/lib.

  • If you're using mocks, copy easymock.jar into the web application lib directory.

  • If you're using the StrutsUT traditional solution, modify the Struts configuration file (it is most likely named struts-config.xml) in %CONTEXT_PATH%/WEB-INF. Search for the following lines in the file:

    <controller processorClass="org.apache.struts.action.RequestProcessor"
    
    </controller>

    And replace that with:

    <controller processorClass="org.jingle.unittest.struts.StrutsUnitTestRequestProcessor"
    
    </controller>

    If you're using the Tiles plug-in with Struts, replace the following lines:

    <controller
    
        processorClass="org.apache.struts.tiles.TilesRequestProcessor"
    
    </controller>

    with:

    <controller
    
        processorClass="org.jingle.unittest.struts.TilesUnitTestRequestProcessor"
    
    </controller>
  • If you're using the StrutsUT AspectJ solution, extract StrutsTestCaseAspect.java from the StrutsUT .jar file and compile with your source code and test cases using the AspectJ compiler.

Now, the test case is ready to be launched by the JUnit test runner.

Conclusion

Struts is a widely used framework for web applications. Cactus is a web application unit-test framework. They are two sharp weapons for web application developers, but there are some limitations when unit testing Struts applications using Cactus. StrutsUT provides two solutions to solve this problem by introducing a join point into the Struts execution flow. The traditional solution extends the Struts Request Processor and Cactus test-case base class. The AspectJ solution keeps the Cactus and Struts framework untouched but acquires the source code and test cases compiled with the AspectJ compiler. In the future, this limitation will be removed if the AspectJ compiler supports runtime weaving.

References

  • Download StrutsUT
  • Download the sample code in this article
  • JUnit
  • EasyMock
  • Cactus
  • Struts
  • HttpUnit
  • Using Apache Cactus
  • AspectJ

Lu Jian is a senior Java architect/developer with four years of Java development experience.


Return to ONJava.com.

Prev  [1] [2] [3] [4] [5] 

Close    To Top
  • Prev Article-Java:
  • Next Article-Java:
  • Now: Tutorial for Web and Software Design > Java > Java Servlets > Java Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction