- Issues with JUnit testing of EJBs
- Example Code
- Developing Local Tests
- The Ant Task
- Conclusion
Developing Local Tests
Because the testXXX method is executed within the same JVM as the Enterprise Java Beans, it is relatively simple to test them. Note that because the beginXXX and endXXX methods are not strictly required by Cactus, if the test involves only the local interface of a bean, these two methods can be left out. The testXXX method is required, however.
Therefore, using the sample beans above, here is a test that checks that the session bean can successfully call the method on the session bean retrieveParentByName(String):
package com.dzrealms.example.entity; import org.apache.cactus.ServletTestCase; import javax.naming.InitialContext; /** * Example Cactus Test */ public class ExampleCactusTest extends ServletTestCase { public void testSessionAccess() throws Exception { InitialContext ic = new InitialContext(); Object o = ic.lookup("example/local/ExampleSession"); ExampleSessionLocalHome home = (ExampleSessionLocalHome)o; ExampleSessionLocal local = home.create(); local.retrieveParentByName("test"); assertTrue("Test is null", local == null); } }
There are a few things to mention about this example:
- By placing the test case inside of the same package as the objects we are testing, no imports are needed. It saves a little bit of testing.
- Because we are inside of the same JVM, we can use a simple initial context and not be concerned with setting any properties for that context.
- Because we are inside of the same JVM, we can access the local interface for the session bean and retrieve a local interface for the entity bean.
To be able to test the remote interface as well, similar code is added to either the beginXXX method or the endXXX method. There is no difference other than determining in which order they are run. Here is the additional method added to the test class:
public void endSessionAccess() throws Exception { Properties p = new Properties(); p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); p.put("java.naming.provider.url", "jnp://localhost:1099"); p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); InitialContext ic = new InitialContext(p); Object o = ic.lookup("example/remote/ExampleSession"); o = PortableRemoteObject.narrow(o, ExampleSessionRemoteHome.class); ExampleSessionRemoteHome home = (ExampleSessionRemoteHome)o; ExampleSessionRemote remote = home.create(); remote.retrieveParentByName("test"); assertTrue("Test is null", remote == null); }
There are a couple of things to note about this example:
- Because this code will be executed in the "client" JVM, it has no knowledge of the application server and needs to be told how to retrieve its context. Thus the initial context is passed a java.util.Properties object with the necessary information. In this example, I am running against a JBoss instance on the local machine.
- The remote home and interface is retrieved, even though we are inside of the same class that executed inside of the server JVM and retrieved the local home and interface.