IBM®
Skip to main content
    Country/region [select]      Terms of use
 
 
      
     Home      Products      Services & solutions      Support & downloads      My account     

developerWorks > WebSphere >
developerWorks
Unit Testing EJBs in VisualAge for Java using JUnit
e-mail it!
Contents:
Introduction
Writing test cases for EJBs
Executing test cases
Problems in unit testing EJBs
Additional information about JUnit
Things that JUnit can't do
Conclusion
Resources
About the authors
Rate this article
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)

Sultan Ahamed Kaja, Senior Software Engineer, IBM Global Services India
Sunil Mahamuni (msunil@in.ibm.com), Senior Software Engineer, IBM Global Services India

30 Oct 2002

This article explains how to use JUnit to unit test EJBs in VisualAge for Java. The article describes JUnit and explains how to use it to create and execute test cases.

© Copyright International Business Machines Corporation 2002. All rights reserved.

Introduction
This article is for VisualAge© for JavaTM users who want to unit test their EJBs and develop test cases for them. The article is based on VisualAge for Java 3.5.3 and JUnit 3.7. The article describes JUnit, the difficulties in unit testing EJBs, and the steps involved in developing test cases.

Unit tests are written from a programmer's perspective. They ensure that a particular method of a class successfully performs a set of specific tasks. Each test confirms that a method produces the expected output when given a known input. Effective testing is essentially part of effective programming. By using the JUnit test framework, you can easily and incrementally build a test suite that will help you measure your progress, spot unintended side effects, and focus your development efforts.

Writing test cases for EJBs
Here is an example of an EJB that has a business method named addition that takes two input variables of type int, adds them, and returns the result:

/** 
* This is a Session Bean Class 
*/ 
public class SampleEjbBean implements SessionBean {  
   private javax.ejb.SessionContext mySessionCtx = null;  
   final static long serialVersionUID = 3206093459760846163L; 
    
/** 
 * Insert the method's description here. 
 * Creation date: (8/10/02 1:16:33 PM) 
 * @return int 
 * @param a int 
 */  
//The Business method     
 
public int addition(int a,int b) {  
   return a+b; 
} 
 
public void ejbActivate() throws java.rmi.RemoteException {...} 
public void ejbCreate() throws javax.ejb.CreateException, java.rmi.RemoteException {...} 
public void ejbPassivate() throws java.rmi.RemoteException {....} 
public void ejbRemove() throws java.rmi.RemoteException {.....} 
public javax.ejb.SessionContext getSessionContext() {  
   .....  
} 
public void setSessionContext(javax.ejb.SessionContext ctx) throws java.rmi.RemoteException {  
   .....     
} 
}

Use the following steps to create a test case for the EJB.

  1. Create a test class by extending JUnit.framework.TestCase. Naming convention: if the name of the bean is SampleEjbBean, then name the test class SampleEjbBeanTest. For example:
    public class SampleEjbBeanTest extends JUnit.framework.TestCase{.
  2. Create a class variable of type remoteInterface of the Bean. For example:
    SampleEjb remoteInterface
  3. Create a static instance of the test class:
    static {   
       instance = new SampleEjbBeanTest("");  
    }

    Since the instance is used as a parameter for the run method of the TestRunner to execute the TestClass.//main method and execute the test case, you can execute the test case in either SwingUI or TextUI:

    public static void main(String args[]) 
    {  
       if (args.length > 0){   
          if (args[0].equals("SWING")) {   
             JUnit .swingui.TestRunner.run(instance.getClass());    
          }   
          else {  
             JUnit .textui.TestRunner.run(instance.getClass()); 
          }   
      }   
      else { 
     
          //formatting the Output   
          System.out.println("************************************");    
          String className = instance.getClass().getName();  
          className = className.substring(className.lastIndexOf(".")+1); 
          System.out.println("Test Report of:"+className); 
          System.out.println("************************************");  
          JUnit.textui.TestRunner.run(instance.getClass());  
       } 
    }
  4. Next, Create a method for connecting the EJB bean running on the server and create the handle for the remote Interface:
    1. Add the initial context to the HashMap. For example:
      env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.ejs.ns.jndi.CNInitialContextFactory
    2. Add the URL to the HashMap. For example:
      env.put(Context.PROVIDER_URL, "iiop://localhost:900");
    3. Create the InitialContext object. For example:
      javax.naming.InitialContext ic =new javax.naming.InitialContext(env);
    4. Construct a homeInterface of the Bean by looking up the EJB Alias name in the naming server. For example:
      SampleEjbHome homeInterface = (SampleEjbHome) ic.lookup("SampleEjb");
    5. Create a remoteInterface by invoking the create method on homeInterface. For example:
      remoteInterface = homeInterface.create();
      Public void getConnection()  
         {   
            getinfo("Running " + this.toString()); 
           
            java.util.Hashtable env = new Hashtable(); 
           
         //Adding the Initial Context to the HashMap. 
         env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.ejs.ns.jndi.CNInitialContextFactory 
      ");   
       
            env.put(Context.PROVIDER_URL, "iiop://localhost:900");  
            try   
            {    
               getinfo("Creating an initial context");    
               javax.naming.InitialContext ic =new javax.naming.InitialContext(env);    
               getinfo("Looking for the EJB " + "SampleEjb");    
               SampleEjbHome homeInterface =    
               (SampleEjbHome) ic.lookup("SampleEjb");    
               getinfo("Creating a new EJB instance");    
               remoteInterface = homeInterface.create();   
            }   
            catch (NamingException e)   
            {  
               getinfo(e.toString());    
               fail();   
            }   
            catch (Exception e)   
            {    
               getinfo("Create Exception");    
               getinfo(e.toString());    
               fail();   
            } 
      }
  5. In the setup method used for setting up the fixture (for example, opening a network connection, opening a file), this method is called before a test is executed. Call the getConnection() method so that the test case gets initialized along with the EJB settings.
    public void setUp() throws Exception 
    {  
       ...... 
       /*Invoking the getConnection method*/  
       getConnection(); 
    }
  6. Create the test case for the methods. Use the following naming convention: name the test case testXXXX(testAddition). In testMethod(testAddition), invoke the business method (addition) from the remoteInterface object. For example:
    int result=remoteInterface.addition(10,15); 
     
    public void testAddition() {  
       try{    
     
          int result=remoteInterface.addition(10,15);   
          getinfo("----------------------------------");   
          getinfo("Success without Exception");   
          assertEquals(25,result);  
     
          }   
          catch(Exception e){  
             fail("Fail"+e);   
             System.out.println("Error"+e);  
          } 
    }

Other methods developed for the report:

public void getinfo(boolean msgObj) 
{  
   System.out.println(msgObj); 
}  
 
public void getinfo(String msg) 
{  
   System.out.println(msg); 
}

Executing test cases

  1. Deploy the EJB.
  2. Start the WebSphere Test Environment and the Persistence Name Server on VisualAge for Java.
  3. Add the EJB to the server configuration.
  4. Start the EJB server.
  5. Execute the test class from VisualAge for Java by invoking the main method. Here is the result:
    ************************************ 
    Test Report of: SampleEjbBeanTest 
    ************************************ 
    . Running testAddition(com.prudential.retserv.chart.servlet.SampleEjbBeanTest) 
    Creating an initial context 
    Looking for the EJB SampleEjb 
    Creating a new EJB instance 
    ---------------------------------- 
    Success without exception  
     
    Time: 15.984 
     
    OK (1 tests)

In this way, you can develop test cases and unit test the EJB from where it has been deployed.

Problems in unit testing EJBs
Unit tests run best when they run individually, in isolation, and quickly. A test case typically constructs the objects it is testing. However, sometimes the object being tested is dependent on the behavior of other objects. In such situations, the test case builds a test harness to "stub out" the needed behavior. Such a test harness has the same interface as the real system, but doesn't actually do anything, and "fools" the unit being tested into thinking that it has been tested with the system. EJBs usually rely on the context provided by their container, and without that context, most EJBs will not function. The test case should invoke the EJB from the container where it has been executed. Testing EJB objects in their native environment is also possible, but the validity of the test might be compromised. So the test case developed should invoke the EJBs in the container where it has been deployed and is executing.

Additional information about JUnit

  • JUnit tests let you produce higher quality code more quickly.
  • JUnit tests check their own results and provide immediate feedback.
  • JUnit tests can be composed into a hierarchy of test suites.
  • Writing JUnit test cases can be done quickly and inexpensively.
  • JUnit tests can easily be done by the developer.
  • JUnit tests are written in Java.
  • JUnit can test EJBs, servlets, and threaded programs.
  • JUnit is designed around two key design patterns: the Command pattern and the Composite pattern.
  • JUnit is free.

Things that JUnit can't do

  • JUnit does not separate test data from test code.
  • JUnit can't unit test Swing GUIs, JSPs, or HTML.
  • JUnit tests don't take the place of functional testing. If all of your unit tests succeed, that does not mean that the software is ready to ship.
  • JUnit can't unit test server-side Java code. Several Xunit testing frameworks are designed for unit testing server-side Java code.

Conclusion
Unit tests are important. They decrease development time and increase code quality. When unit tests are written first as a suite before the EJB code is developed, they provide a powerful validation and regression tool. JUnit can make the job of writing unit test cases easier.

Top of page

Resources

About the authors

Sultan Ahamed Kaja is a Senior Software Engineer in IBM Global Services India. He works on J2EE-related projects in the financial services sector. His past experience includes Java testing, Java programming, and programming for WebSphere Portal server and Lotus K-Station server. He has a B.S. in computer science and is pursuing an M.S. in Software Systems.


Sunil Mahamuni is a Senior Software Engineer and Team Leader in IBM Global Services India. He works in the financial services sector on banking and insurance applications. His past experience includes J2EE and wireless development projects. He has an M.S. in computer science from Osmania University in India. You can reach Sunil at msunil@in.ibm.com .



e-mail it!
Rate this article

This content was helpful to me:

Strongly disagree (1)Disagree (2)Neutral (3)Agree (4)Strongly agree (5)

Comments?



developerWorks > WebSphere >
developerWorks
    About IBM Privacy Contact