2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.support.persistence;
18 import javax.naming.InitialContext;
19 import javax.naming.NamingException;
20 import javax.sql.DataSource;
22 import org.dbunit.IDatabaseTester;
23 import org.wamblee.support.jndi.StubInitialContextFactory;
26 * This class is the entry point for JPA tests. Test code should construct a
27 * JpaTester in the <code>@Before</code> method and call {@link #start()} on it
28 * in that method. Also, test code should call {@link #stop()} on it in the
29 * <code>@After</code> method.
31 * This class is constructed with a description of the persistence unit to be
32 * tested. The principle is that an existing <code>persistence.xml</code> can be
33 * tested without change in unit test code.
35 * It then takes care of the following:
37 * <li>Creating an inmemory database for testing (default) or connecting to an
38 * external database. See {@link DatabaseBuilder} for more information on how a
39 * databse is obtained.</li>
40 * <li>Drop all database tables that are related to the persistence unit under
41 * test, including JPA provider specific tables.</li>
42 * <li>Creating a datasource for the database and make the datasource available
44 * <li>Creating the entity manager factory for JPA and configuring it in such a
45 * way that schema creation happens. (Typically, schema creation will be
46 * disabled in the persistence.xml but this utility enables it for unit test).</li>
47 * <li>Creating a DBUnit database tester which is appropriately configured for
48 * the persistence unit under test.</li>
51 * The main entry point for all this functionality is the
52 * {@link PersistenceUnitDescription} which describes the persistence unit and
53 * must be provided at construction of the <code>JpaTester</code>
55 * NOTE: Persistence XML files should be explicitly configured with the classes
56 * that are part of the persistence unit since scanning of classes does not work
57 * correctly in a unit test environment. This is currently the only limitation.
59 public class JpaTester {
61 private PersistenceUnitDescription persistenceUnit;
63 private DataSource dataSource;
64 private DatabaseUtils dbUtils;
65 private JpaBuilder jpaBuilder;
66 private IDatabaseTester dbTester;
69 * Constructs the tester.
71 * @param aPersistenceUnit
72 * Persistence unit under test.
74 public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
75 persistenceUnit = aPersistenceUnit;
79 * Starts the tester. This must be called prior to running the test.
83 public void start() throws Exception {
84 db = DatabaseBuilder.getDatabase();
85 dataSource = db.start();
87 // NOTE: adding datasource to JNDI is no longer needed for
88 // JPA testing, but is nice to have available for other uses.
89 StubInitialContextFactory.register();
91 InitialContext ctx = new InitialContext();
92 ctx.bind(persistenceUnit.getJndiName(), dataSource);
93 } catch (NamingException e) {
94 throw new RuntimeException("JNDI problem", e);
97 dbUtils = new DatabaseUtils(dataSource, persistenceUnit.getTables());
100 dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
102 jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db.getPassword(), persistenceUnit);
105 // db tester should be created after Jpa builder because jpa builder
107 // tables that the tester looks at when it is initialized.
108 dbTester = dbUtils.createDbTester();
112 * Stops the tester. This must be called after the test.
115 if (jpaBuilder != null) {
118 if (dbUtils != null) {
126 public Database getDb() {
130 public DataSource getDataSource() {
134 public IDatabaseTester getDbTester() {
138 public DatabaseUtils getDbUtils() {
142 public JpaBuilder getJpaBuilder() {
146 public PersistenceUnitDescription getPersistenceUnit() {
147 return persistenceUnit;