◆ Problem
You would like to test a container-managed persistence (CMP) entity bean.
◆ Background
Part of the point of using container-managed persistence is to let the application server—specifically the EJB container—provide the vast majority of entity bean code for you. Because we recommend that you don’t test the platform, it seems quite reasonable not to test CMP entity beans at all. It seems reasonable, but it is not.
Even though you might not need to write much code for CMP entity beans—
simply declare interfaces and methods—you still need to specify your CMP entity bean at least in enough detail that the container can fill in the rest. This is why we recommend that you try testing the CMP entity bean meta data, rather than the bean itself (see recipe 11.5, “Test CMP meta data outside the container”). We have found that, much of the time, this is enough, but we recognize that there are times when you need more confidence than that.
If you have encountered specific, recurring defects with CMP entity beans, then we recommend writing at least some tests to guide future work. You might be work- ing with a slightly defective application server, you might be working with CMP entity beans that someone else wrote (and for which there are no tests), or per- haps you are learning to write CMP entity beans and would like to use tests to pro- vide ongoing feedback while you learn.13 Whatever the reason, we understand that some programmers want to test “the real thing” and not “just the meta data.”
If you fall into that category, then this recipe is for you.
13This is an excellent technique for learning a new programming language. When J. B. took his first steps in Squeak Smalltalk, he wrote Learning Tests using SUnit, the Smalltalk equivalent to (and predecessor of) JUnit.
398 CHAPTER 11
Testing Enterprise JavaBeans
◆ Recipe
The most direct way to test a CMP entity bean is to test it inside the container. If you wish to do this, then we highly recommend using Cactus. In this recipe we will describe the kinds of tests you likely need to write. To write them, use the same techniques we describe in recipe 11.2. To test a CMP entity bean requires testing these features:
■ The mapping between the entity bean class and the database table
■ The mapping between the entity bean container-managed fields and the table columns
■ Container-managed relationships, if any
■ All the finder methods
We discuss testing security and transaction attributes elsewhere (chapter 13, “Testing J2EE applications”) because these issues apply to more than just CMP entity beans.
You can test both levels of mappings (class/table and field/column) by storing a few objects and loading them back. Be sure to exercise each field of the entity bean at least once. You can test relationships by storing an empty collection of related objects, loading it back, adding an object or two, and then storing it once again. As for the finder methods, unfortunately there is no substitute for setting up test data, invoking the finder, and verifying the results.
In chapter 10 we discussed the exorbitant cost of testing against live data from a database, so we implore you to keep this in mind as you test your CMP entity bean finder methods. Once you gain some confidence writing EJBQL queries—or even if you have that confidence already—move your live-container tests to a separate test suite. Execute those tests using a background automated build tool such as Cruise Control. When someone changes a finder method, he must execute those tests to verify the change; otherwise, let Cruise Control run them in the background as a safety net against unexpected changes.
Finder methods are the one part of CMP entity beans that are the most prone to error, so we recommend that you test them thoroughly. At the same time, we recognize that those tests are expensive to execute, which is why we recommend executing them in the background. Aside from finder methods, though, we rec- ommend testing just CMP entity bean meta data, since that is what you write. See recipe 11.5 for details.
399 Test a CMP entity bean
◆ Discussion
You will notice that this list of tests does not include, for example, verifying the entity bean in the presence of null values, its unique indices, duplicate keys, or invalid foreign keys. The application server writes code to handle those situations, and not you, so you ought to focus on testing how you react to these conditions.
Presumably you have session beans that invoke this CMP entity bean. Rather than test whether the EJB container correctly throws DuplicateKeyException (which is outside your control, anyway), test how your session bean reacts when the entity bean throws a DuplicateKeyException.14 Don’t test the platform.
We have been on projects where it has been suggested to test CMP entity beans
“through the End-to-End Tests.” This would mean using black-box—“from the GUI, to the back end, and back”—tests to verify that the entity beans fit into the overall application correctly. We strongly recommend that you resist the urge to do this. First, End-to-End Tests are not well-suited to isolate defects, as they involve the entire application. These tests are meant to show that you have implemented fea- tures the way they were specified. Next, consider the variety of tests you might want to write for a single entity bean, checking all the finder methods for various bound- ary conditions and so on. Imagine how slow a test suite you would have if you tested all these boundary conditions with a web container, an EJB container, EJB-to-EJB communication, and all the business logic executing around it. Do not go down that road, as it will only lead you to pain and misery. We have been that way. If you are going to test CMP entity beans in a live container, then test them in isolation.
One more note, related to deployment: if your tests themselves are going to set up and tear down test data in the database, be careful with your choice of entity bean commit options. If your test uses JDBC (whether directly, or indirectly through a tool such as DbUnit) to create and remove test data while your EJBs are running, then do not deploy your entity beans using “exclusive database access,” also known as “commit option A.” Certainly your entity beans do not have exclusive access to the database, so especially if your tests change the live data in the middle of a transaction, you will not be able to assume exclusive access to the database for your entity beans. You can detect this problem if your tests fail because of unex- pected duplicate key or foreign key problems, or your entity beans appear to have stale data during your tests but not in production. Consult the EJB specification or
14We recommend using MockEJB and deploying a crash test dummy version of the entity bean that always throws the desired exception. See recipe 11.1 for details.
400 CHAPTER 11
Testing Enterprise JavaBeans
an EJB-specific book such as Mastering Enterprise JavaBeans15 for details on the vari- ous commit options.
◆ Related
■ 11.1—Test a session bean method outside the container