Tuesday, November 4, 2008

Using OpenEJB for unit testing with Hibernate on Netbeans

EJB3 has simplified EJB development a lot. However, it imposed new difficulties on out-of-container testing with the use of dependency injection. OpenEJB provides a way of to do EJB testing within J2Se environment in a lightweight container.

I am using Hibernate as the JPA implementation in current development, I would like to demonstrate how to test EJB under Netbeans 6.1 using OpenEJB.

Here are the steps:

1. Download OpenEJB from http://openejb.apache.org/, the current version is 3.1. Unzip the file, you may find all the required jar file under {somewhere to put the unzipped files}:\openejb-3.1\lib.

2. In Netbeans, under Tools --> Library --> new Library, create a library called openejb.

3. Assume that you have an existing EJB project with a test Stateless Session Bean as following:

@Stateless
public class MyTestBean implements MyTestLocal {

public String sayHello() {
System.out.println("hahahah");

return "haha";
}

}

Here's the persistence configuration:
<persistence-unit name="my-ejbPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>myds</jta-data-source>
</persistence-unit>


4. Add ejb-jar.xml into configuration files of the EJB project as the followings:

<ejb-jar/>


The above declaration is used for telling the OpenEJB container to scan the jar file containing the EJBs and deploy it along with any annotated beans it may contain. http://openejb.apache.org/3.0/application-discovery-via-the-classpath.html

5. Create a J2SE project named testapp. Add the openejb and the EJB project as Library. If you use MySQL as the database, please add the mysql connectorJ library as well.

6. Create a unit test in the J2SE project.

public class NewJUnitTest extends TestCase {

private InitialContext initialContext;

public NewJUnitTest() {
}

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Before
public void setUp() {

//Init the OpenEJB Container
try {
Properties p = new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
//Config the DataSource with MySQL
p.put("myds", "new://Resource?type=DataSource");
p.put("myds.JdbcDriver", "com.mysql.jdbc.Driver");
p.put("myds.JdbcUrl", "jdbc:mysql://localhost:3306/mydb");
p.setProperty("myds.UserName", "test");
p.setProperty("myds.Password", "test");

//It's specially for MySQL where hibernate.dialect must be explicitly set
p.put("my-ejbPU.hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");

initialContext = new InitialContext(p);
} catch (NamingException ex) {

System.err.println(ex.getMessage());
}
}



//Here's the testing Code
@Test
public void testSayHello(){
try {

Object object = initialContext.lookup("MyTestBeanLocal");
assertNotNull(object);
assertTrue(object instanceof MyTestLocal);
MyTestLocal mt = (MyTestLocal) object;
assertEquals("haha",mt.sayHello());

} catch (NamingException ex) {
assertFalse(true);
System.err.println(ex.getMessage());
}
}

@After
public void tearDown() {
}

}


After all, you can test any Entity or SessionBeans in a J2SE environment. When you start the OpenEJB container in SetUp(), the Persistence Provider Implementation will check the entitiy mappings with Database. DBUnit could also be introduced if you would like to test Entity Beans.

No comments: