code style improvements.
[utils] / test / enterprise / src / main / java / org / wamblee / test / 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.test.persistence;
17
18 import javax.naming.InitialContext;
19 import javax.naming.NamingException;
20 import javax.sql.DataSource;
21
22 import org.dbunit.IDatabaseTester;
23 import org.wamblee.test.jndi.StubInitialContextFactory;
24
25 /**
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.
30  * 
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.
34  * 
35  * It then takes care of the following:
36  * <ul>
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
43  * through JNDI.</li>
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>
49  * </ul>
50  * 
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>
54  * 
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.
58  */
59 public class JpaTester {
60
61     private PersistenceUnitDescription persistenceUnit;
62     private Database db;
63     private DataSource dataSource;
64     private DatabaseUtils dbUtils;
65     private JpaBuilder jpaBuilder;
66     private IDatabaseTester dbTester;
67
68     /**
69      * Constructs the tester.
70      * 
71      * @param aPersistenceUnit
72      *            Persistence unit under test.
73      */
74     public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
75         persistenceUnit = aPersistenceUnit;
76     }
77
78     /**
79      * Starts the tester. This must be called prior to running the test.
80      * 
81      * @throws Exception
82      */
83     public void start() throws Exception {
84         db = DatabaseBuilder.getDatabase();
85         dataSource = db.start();
86         
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();
90         try {
91             InitialContext ctx = new InitialContext();
92             ctx.bind(persistenceUnit.getJndiName(), dataSource);
93         } catch (NamingException e) {
94             throw new RuntimeException("JNDI problem", e);
95         }
96
97         dbUtils = new DatabaseUtils(dataSource);
98         dbUtils.start();
99         dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
100
101         jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db.getPassword(), persistenceUnit);
102         jpaBuilder.start();
103     }
104
105     /**
106      * Stops the tester. This must be called after the test.
107      */
108     public void stop() {
109         if (jpaBuilder != null) {
110             jpaBuilder.stop();
111         }
112         if (dbUtils != null) {
113             dbUtils.stop();
114         }
115         if (db != null) {
116             db.stop();
117         }
118     }
119
120     /**
121      * Gets the database. 
122      * @return Database. 
123      */
124     public Database getDb() {
125         return db;
126     }
127
128     /**
129      * Gets the datasource. 
130      * @return Datasource. 
131      */
132     public DataSource getDataSource() {
133         return dataSource;
134     }
135
136     /**
137      * Gets the database utilities. 
138      * @return Database utilities. 
139      */
140     public DatabaseUtils getDbUtils() {
141         return dbUtils;
142     }
143
144     /**
145      * Gets the jpa builder. 
146      * @return JPA builder. 
147      */
148     public JpaBuilder getJpaBuilder() {
149         return jpaBuilder;
150     }
151
152     /**
153      * Gets the persistence unit. 
154      * @return Persistence unit. 
155      */
156     public PersistenceUnitDescription getPersistenceUnit() {
157         return persistenceUnit;
158     }
159
160 }