lthough the EJB 3.0 specification has yet to be released, it is already generating much interest in the software development community by both proponents and opponents alike. All recognize the need to find more productive methods for developing software; the debate centers on whether, and to what extent, EJB 3.0 will play a role in this new landscape. Debate notwithstanding, the release of the EJB 3.0 public draft and preliminary support in JBoss mean that now is a great time to explore this influential technology. In fact, reports of the use of EJB 3.0 in production systems are already emerging.
This article is the third in a three-part series exploring EJB 3.0 as defined in the public draft. Each article has introduced particular concepts from the specification and has walked you through the implementation of these techniques using JBoss. The first article introduced EJB 3.0, the philosophy behind it, and illustrated how to use it to develop Enterprise Bean Components. The second article introduced you to developing persistent entities with EJB 3.0. This third article will explore more advanced topics such as transaction management, callbacks, interceptors, and exceptions.
In this article I'll extend the online music store application (which was used extensively in the first two articles) following a test-driven approach. What this means is that for each concept that is explored in this article you will first see how to write a unit test verifying the expected behavior of the feature being added. Next you will see how to implement that feature using EJB 3.0.
For an overview of the music store application, please consult the earlier two articles. The storefront is shown in Figure 1.
|Figure 1. Music Store: The music store allows products to be browsed, added to a shopping cart, and eventually purchased. |
Unit Testing Enterprise Beans
Enterprise Beans in EJB 3.0 are easier to test than EJBs written to prior versions of the specification. This is largely because in the 3.0 specification EJBs are simply POJOs annotated with specific EJB 3.0 annotations. Also, one of the very nice features of the JBoss implementation is that it can be used outside the JBoss Application Server in an embedded configuration. In this article you will see how to unit test EJBs using the JBoss embedded EJB 3.0 container.
To run the JBoss embedded container all you need to do is to download the distribution from JBoss, and place the JAR and configuration files on the classpath of your application. When your application (or unit test in this case) is ready to start the embedded container it uses the EJB3StandaloneBootstrap class to bootstrap the container. Listing 1 shows an abstract JUnit test case that for each unit test starts the embedded container and populates a sample database with known test data:
The data test being used to unit test the music store's persistent entities is loaded via DbUnit and contains the data shown in Listing 2.
Through the rest of this article you will write unit tests that subclass the above base test case. These test cases can be written assuming that the container and the database are in a known state.
Using this base test case you can now very easily write a unit test for the MusicStoreDAO developed in the last article on EJB 3.0 persistence. For example, you can test the findArtistById method of the DAO by taking the following steps:
- Start the embedded container (performed in the setup method of the parent test case).
- Load sample data (performed in the setup method of the parent test case).
- Retrieve a reference to the MusicStoreDAO stateless session bean through JNDI.
- Invoke the findArtistById method with a known artist id.
- Lastly, verify that the artist retrieved matches the artist id supplied.
This is very easy with the embedded EJB 3.0 container and the above base test case. The code is shown below:
public class MusicStoreDAOTest extends BaseTestCase
public void testFindArtistById() throws Exception
IMusicStoreDAO dao = (IMusicStoreDAO) getInitialContext().lookup(
Artist artist = dao.findArtistById(1);
assertEquals("Norah Jones", artist.getName());
As the above example illustrates, with the JBoss embedded EJB 3.0 container it really is quite easy (and fast) to unit-test EJBs.