JaVa
   

Testing EJBs with Cactus

Overview

This chapter demonstrates the techniques for unit-testing Enterprise JavaBeans (EJBs) using Cactus. At the time of this writing, Cactus does not include any EJB redirectors. However, you can use any of its TestCases (ServletTestCase, FilterTestCase, or JspTestCase) for testing EJBs. Cactus offers powerful incentives for testing EJBs. Although there are alternate ways that can be used to test EJBs, such as JUnit or mock objects, the following benefits are a direct result of using Cactus:

Let's now take a look at a simple local stateless session bean (local SLSB). The following listing gives the code for the OrderReportBean. The OrderReportBean SLSB returns a list of orders placed within a given date range:

public class OrderReportBean implements SessionBean {
 private String queryStatement = "SELECT ID, " + "TOTAL " + "FROM ORDER order " +
 "WHERE order.ORDER_DATE BETWEEN ? AND ? "; 
 public List ordersByDateRange(java.util.Date startDate, java.util.Date endDate) throws EJBException{
 ResultSet rs = null;
 PreparedStatement stmt=null;
 Connection conn = null;
 List records = null;
 try {
 conn = getConnection(); //getConnection() not listed here
 stmt = conn.prepareStatement(queryStatement);
 stmt.setDate(1, new java.sql.Date(startDate.getTime()));
 stmt.setDate(2, new java.sql.Date(endDate.getTime()));
 rs = stmt.executeQuery();
 records = new ArrayList();
 Map record = new HashMap();
 while(rs.next()){
 record.put(rs.getInt(1), rs.getDouble(2));
records.add(record);
 }
 }
 catch (SQLException e){
 throw new RuntimeException(e, "unable to get orders by date range. " + queryStatement);
 }
 finally{
 try {
 if (rs!=null)rs.close();
 if (stmt!=null)stmt.close();
 if (conn!=null)conn.close();
 }
 catch (SQLException e){
 throw new RuntimeException(e, "unable to get orders by date range. " + queryStatement);
 }
 }
 return records;
 }
 public void ejbActivate() throws EJBException{} public void ejbPassivate() throws EJBException {}
 public void ejbCreate() throws EJBException {}
 public void ejbRemove() throws EJBException {}
 public void setSessionContext(javax.ejb.SessionContext context) throws EJBException {}
}


Writing a test for the OrderReportBean is straightforward. First, we extend ServletTestCase. Then, we perform a lookup on our EJB in the setUp() method. OrderReportBeanTest gets its environment properties from the container; thus we do not specify any JNDI properties before calling new InitialContext():

public void setUp()throws Exception{
 OrderReportHome home = (OrderReportHome)new InitialContext().lookup("ejb/xptoolkit/OrderReport");
 orderReport = home.create();
 start = formatter.parse("01/01/2001");
 end = formatter.parse("01/01/2035");
 createTestOrders(); // insert some test orders
}


We test the ordersByDateRange method in our EJB by verifying that it returns a non-empty list:

 public void testOrdersByDateRange() { List records = orderReport.ordersByDateRange (start, end);
 assertTrue(records.size() > 0);
 }


At last, we clean up the test data:

 public void tearDown()throws Exception{
 deleteTestOrders(); //delete test orders
 }


The following listing contains the complete code for OrderReportBeanTest.

package xptoolkit;
import java.text.SimpleDateFormat;
import java.util.Date;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;
public class OrderReportBeanTest extends ServletTestCase {
 private OrderReport orderReport;
 private Date start;
 private Date end;
 private SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
 public OrderReportBeanTest(java.lang.String testName) {
 super(testName);
 }
 public void setUp()throws Exception{
 OrderReportHome home = (OrderReportHome)new InitialContext().lookup("ejb/xptoolkit/OrderReport");
 orderReport = home.create();
 start = formatter.parse("01/01/2001");
 end = formatter.parse("01/01/2035");
 createTestOrders(); //create test data – code not shown
 }
 public void testOrdersByDateRange() { List records = orderReport.ordersByDateRange (start, end);
 assertTrue(records.size() > 0);
 }
 public void tearDown()throws Exception{
 deleteTestOrders(); //delete test data - code not shown
 }
 public static void main(java.lang.String[] args) {
 junit.textui.TestRunner.run(suite());
 }
 public static Test suite() {
 TestSuite suite = new TestSuite(OrderReportBeanTest.class);
 return suite;
 } }


To run the test, we use the Ant tasks from the Cactus-Ant integration project. First, we "cactify" the WAR and update the EAR:

...
<cactifywar version="2.3" destfile="${build.dir}/project.war">
<classes dir="${build.dir}"/>
</cactifywar>
<ear update="true" destfile="${build.dir}/project.ear">
<fileset dir="${build.dir}">
<include name="project.war"/>
</fileset>
</ear>
...


The <cactifywar> task adds definitions for the Cactus test redirectors, deployment descriptors, and server-side JARs. To run the test, we use the <cactus> task. The <cactus> task extends the standard <junit> task, and thus inherits all its attributes. In addition, it deploys the EAR, starts the container, runs the tests, and then stops the container.

...
 <cactus earfile="${build.dir}/ejb.ear" fork="yes"
 printsummary="yes" haltonerror="true"
 haltonfailure="true">
 <formatter type="plain" usefile="false"/>
 <containerset>
 <jboss3x dir="${jboss.home}"
 output="serveroutput.txt"/>
 </containerset>
 <test name="xptoolkit.OrderReportBeanTest"/>
 <classpath>
 <pathelement location="${build.dir}"/>
 </classpath>
 </cactus>
...


For complete details on the Cactus-Ant integration, please see http://jakarta.apache.org/cactus/integration/ant/index.html.

In the next section, we go over the process of adding an entity bean to the PetStore app from the previous chapter. The case study also shows how to unit-test an entity bean that uses container-managed persistence (CMP).


JaVa
   
Comments