 | 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.
- 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{.
- Create a class variable of type
remoteInterface of the Bean. For example:
SampleEjb remoteInterface
- 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());
}
}
|
- Next, Create a method for connecting the EJB bean running on the server and create the handle for the remote Interface:
- Add the initial context to the HashMap. For example:
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.ibm.ejs.ns.jndi.CNInitialContextFactory
- Add the URL to the HashMap. For example:
env.put(Context.PROVIDER_URL, "iiop://localhost:900");
- Create the
InitialContext object. For example:
javax.naming.InitialContext ic =new javax.naming.InitialContext(env);
- 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");
- 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();
}
}
|
- 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();
}
|
- 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
- Deploy the EJB.
- Start the WebSphere Test Environment and the Persistence Name Server on VisualAge for Java.
- Add the EJB to the server configuration.
- Start the EJB server.
- 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
.
|

|  |