Java Reference
In-Depth Information
essence, JPA testing isn't much different than testing regular database access code, and
hence most of the techniques explained in chapter 17 apply here. A few differences
and caveats are worth mentioning though, and we cover them in the next subsections.
But first, let's consider some aspects of JPA testing.
W HAT SHOULD BE TESTED ?
JPA programming could be divided in two parts: entities mapping and API calls. Ini-
tially, you need to define how your objects will be mapped to the database tables, typi-
cally through the use of Java annotations. Then you use an EntityManager object to
send these objects to or from the database: you can create objects, delete them, fetch
them using JPA queries, and so on.
Consequently, it's a good practice to test these two aspects separately. For each per-
sistent object, you write a few test cases that verify that they're correctly mapped (there
are many caveats on JPA mapping, particularly when dealing with collections). Then
you write separate unit tests for the persistence code itself (such as DAO objects). We
present practical examples for both tests in the next subsections.
T HE EMBEDDED DATABASE ADVANTAGE
As we mentioned in section 17.1.3, unit tests must be fast to run, and database access
is typically slow. A way to improve the access time is to use an in-memory embedded
database, but the drawback is that this database might not be totally compatible with
the database the application uses.
But when you use JPA , database compatibility isn't an issue—quite the opposite.
The JPA vendor is responsible for SQL code generation, 5 and vendors typically sup-
port all but the rarest databases. It's perfectly fine to use a fast embedded database
(like HSQLDB or its successor, H2 ) for unit tests. Better yet, the project should be set
in such a way that the embedded database is used by default, but databases could be
easily switched. That would take advantage of the best of both worlds: developers
would use the fast mode, whereas official builds (like nightly and release builds)
would switch to the production database (guaranteeing the application works in the
real scenario).
C OMMITMENT LEVEL
JPA operations should happen inside a transaction, which typically also translates to a
vendor-specific session. A lot of JPA features and performance depends on the transac-
tion/session lifecycle management: objects are cached, new SQL commands are issued
on demand to fetch lazy relationships, update commands are flushed to the database,
and so on.
On the other hand, committing a transaction is not only an expensive operation,
but it also makes the database changes permanent. Because of that, there's a tendency
5
This is the ideal scenario; some applications might still need to manually issue a few SQL commands because
of JPA bugs or performance requirements. These cases are rare, though, and they could be handled separately
in the test cases.
 
 
 
 
 
 
Search WWH ::




Custom Search