How to write TestCase for OpenJPA?
OpenJPA Unit Tests are JUnit Tests. The base JUnit TestCase
org.junit.TestCase
has been extended to facilitate common initialization steps or configuration settings required for unit testing OpenJPA. As a test developer, you should inherit your test class from one of the extended TestCases. This also helps the test you write to be integrated with OpenJPA test corpus of approximately 2000 test cases in 400 classes.
The inheritance hierarchy is:
junit.framework.TestCase +-- org.apache.openjpa.persistence.test.PersistenceTestCase +-- org.apache.openjpa.persistence.test.SingleEMFTestCase +-- org.apache.openjpa.persistence.test.SQLListenerTestCase
In general, SingleEMFTestCase
is a good candidate to inherit from. If your test needs to analyze or count number of SQL statements,
SQLListenerTestCase
should be your choice.
Setting up the test
A JUnit test is set up in
setUp()
method. OpenJPA TestCases augment the
setUp()
method to accept a list of arguments. In this list, you should specify:
- the domain classes used by your test
- the configuration properties that are critical to your test
- CLEAR_TABLES or DROP_TABLES : these are constants declared in the superclass which clears the rows or drops the tables altogether.
The following shows an example
setUp()
method
public void setUp() throws Exception { super.setUp(CLEAR_TABLES, // clears records for domain classes Candidate.class, Election.class, // registers Candidate and Election as persistence-capable entity "openjpa.Multithreaded", "true", // sets configuration property as name-value pairs "openjpa.Log", "SQL=TRACE"); }
Configuration of Persistence Unit
Notice that some configuration parameters can be set in the
setUp()
method of test program itself. This is recommended for properties that are important for your test. The non-critical parameters such as database connection properties (unless your test is about some specific aspect of a particular database) are better be specified in
META-INF/persistence.xml
.
Your test may specify the persistent unit via the following:
protected String getPersistenceUnitName() { return "test-eager-fetch"; }
Cleaning Up
Specifying
CLEAR_TABLES
or
DROP_TABLES
in the list of
setUp()
parameters helps to minimize impact of one test on another. Remember that the test you are writing will run with 2000 other tests.
A JUnit TestCase invokes
tearDown()
method on termination.
SingleEMFTestCase
ensures that
tearDown()
method deletes all rows for the domain classes involved in your test. While clear-your-own-mess helps in most situations, you may want the database records to remain for analysis especially when tests are failing. In that case, you may consider suppressing the superclass behavior of
tearDown()
by simply nullifying the method as
public void tearDown() throws Exception { // avoids super class to delete all records }
Naming Convention
Name your test class and test methods with following suggestions:
- Test case must be in a separate sub-package of
or
org.apache.openjpa.persistence.*"
org.apache.openjpa.persistence.jdbc.*"
- Keep the domain classes and Test cases in the same package
- Test case class names must start with "Test" e.g.
TestEagerFetch
- Test method names start with "test" e.g.
.
testUpdateHonoursForeignKeyConstraints()
- Be generously descriptive with camel case e.g.
or
TestEagerFetch
testFetchGroupLocking()
- avoid the obvious e.g.
or
TestSelect
testQuery()
Domain classes
- Prefer annotation over XML Descriptors for O-R Mapping because that helps to colocate relevant information. Unless, of course, the test is specific about variations in behavior across annotation and XML Descriptors.
Comments
- Describe the purpose of the test on class comments
- If the test is related