52e284ee7e8ee073b389c892c87c9e9f282bba65
[utils] / test / enterprise / src / main / java / org / wamblee / support / persistence / JpaTester.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */ 
16 package org.wamblee.support.persistence;
17
18 import javax.sql.DataSource;
19
20 import org.dbunit.IDatabaseTester;
21
22 /**
23  * This class is the entry point for JPA tests. Test code should construct a
24  * JpaTester in the <code>@Before</code> method and call {@link #start()} on it
25  * in that method. Also, test code should call {@link #stop()} on it in the
26  * <code>@After</code> method.
27  * 
28  * This class is constructed with a description of the persistence unit to be
29  * tested. The principle is that an existing <code>persistence.xml</code> can be
30  * tested without change in unit test code.
31  * 
32  * It then takes care of the following:
33  * <ul>
34  * <li>Creating an inmemory database for testing (default) or connecting to an
35  * external database. See {@link DatabaseBuilder} for more information on how a
36  * databse is obtained.</li>
37  * <li>Drop all database tables that are related to the persistence unit under
38  * test, including JPA provider specific tables.</li>
39  * <li>Creating a datasource for the database and make the datasource available
40  * through JNDI.</li>
41  * <li>Creating the entity manager factory for JPA and configuring it in such a
42  * way that schema creation happens. (Typically, schema creation will be
43  * disabled in the persistence.xml but this utility enables it for unit test).</li>
44  * <li>Creating a DBUnit database tester which is appropriately configured for
45  * the persistence unit under test.</li>
46  * </ul>
47  * 
48  * The main entry point for all this functionality is the
49  * {@link PersistenceUnitDescription} which describes the persistence unit and
50  * must be provided at construction of the <code>JpaTester</code>
51  * 
52  * NOTE: Persistence XML files should be explicitly configured with the classes
53  * that are part of the persistence unit since scanning of classes does not work
54  * correctly in a unit test environment. This is currently the only limitation.
55  */
56 public class JpaTester {
57
58     private PersistenceUnitDescription persistenceUnit;
59     private Database db;
60     private DataSource dataSource;
61     private DatabaseUtils dbUtils;
62     private JpaBuilder jpaBuilder;
63     private IDatabaseTester dbTester;
64
65     /**
66      * Constructs the tester.
67      * 
68      * @param aPersistenceUnit
69      *            Persistence unit under test.
70      */
71     public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
72         persistenceUnit = aPersistenceUnit;
73     }
74
75     /**
76      * Starts the tester. This must be called prior to running the test.
77      * 
78      * @throws Exception
79      */
80     public void start() throws Exception {
81         db = DatabaseBuilder.getDatabase();
82         dataSource = db.start();
83
84         dbUtils = new DatabaseUtils(dataSource, persistenceUnit.getTables());
85         dbUtils.dropTables();
86         dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
87
88         jpaBuilder = new JpaBuilder(dataSource, persistenceUnit);
89         jpaBuilder.start();
90
91         // db tester should be created after Jpa builder because jpa builder
92         // creates the
93         // tables that the tester looks at when it is initialized.
94         dbTester = dbUtils.createDbTester();
95     }
96
97     /**
98      * Stops the tester. This must be called after the test.
99      */
100     public void stop() {
101         if (jpaBuilder != null) {
102             jpaBuilder.stop();
103         }
104         if (db != null) {
105             db.stop();
106         }
107     }
108
109     public Database getDb() {
110         return db;
111     }
112
113     public DataSource getDataSource() {
114         return dataSource;
115     }
116
117     public IDatabaseTester getDbTester() {
118         return dbTester;
119     }
120
121     public DatabaseUtils getDbUtils() {
122         return dbUtils;
123     }
124
125     public JpaBuilder getJpaBuilder() {
126         return jpaBuilder;
127     }
128
129     public PersistenceUnitDescription getPersistenceUnit() {
130         return persistenceUnit;
131     }
132
133 }