(no commit message)
[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.wamblee.test.jndi.StubInitialContextFactory;
23
24 /**
25  * This class is the entry point for JPA tests. Test code should construct a
26  * JpaTester in the <code>@Before</code> method and call {@link #start()} on it
27  * in that method. Also, test code should call {@link #stop()} on it in the
28  * <code>@After</code> method.
29  * 
30  * This class is constructed with a description of the persistence unit to be
31  * tested. The principle is that an existing <code>persistence.xml</code> can be
32  * tested without change in unit test code.
33  * 
34  * It then takes care of the following:
35  * <ul>
36  * <li>Creating an inmemory database for testing (default) or connecting to an
37  * external database. See {@link DatabaseBuilder} for more information on how a
38  * databse is obtained.</li>
39  * <li>Drop all database tables that are related to the persistence unit under
40  * test, including JPA provider specific tables.</li>
41  * <li>Creating a datasource for the database and make the datasource available
42  * through JNDI.</li>
43  * <li>Creating the entity manager factory for JPA and configuring it in such a
44  * way that schema creation happens. (Typically, schema creation will be
45  * disabled in the persistence.xml but this utility enables it for unit test).</li>
46  * <li>Creating a DBUnit database tester which is appropriately configured for
47  * the persistence unit under test.</li>
48  * </ul>
49  * 
50  * The main entry point for all this functionality is the
51  * {@link PersistenceUnitDescription} which describes the persistence unit and
52  * must be provided at construction of the <code>JpaTester</code>
53  * 
54  * NOTE: Persistence XML files should be explicitly configured with the classes
55  * that are part of the persistence unit since scanning of classes does not work
56  * correctly in a unit test environment. This is currently the only limitation.
57  */
58 public class JpaTester {
59
60     private PersistenceUnitDescription persistenceUnit;
61     private Database db;
62     private DataSource dataSource;
63     private DatabaseUtils dbUtils;
64     private JpaBuilder jpaBuilder;
65
66     /**
67      * Constructs the tester.
68      * 
69      * @param aPersistenceUnit
70      *            Persistence unit under test.
71      */
72     public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
73         persistenceUnit = aPersistenceUnit;
74     }
75
76     /**
77      * Starts the tester. This must be called prior to running the test.
78      * 
79      * @throws Exception
80      */
81     public void start() throws Exception {
82         db = DatabaseBuilder.getDatabase();
83         dataSource = db.start();
84
85         // NOTE: adding datasource to JNDI is no longer needed for
86         // JPA testing, but is nice to have available for other uses.
87         StubInitialContextFactory.register();
88         try {
89             InitialContext ctx = new InitialContext();
90             ctx.bind(persistenceUnit.getJndiName(), dataSource);
91         } catch (NamingException e) {
92             throw new RuntimeException("JNDI problem", e);
93         }
94
95         dbUtils = new DatabaseUtils(dataSource);
96         dbUtils.start();
97         dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
98
99         jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db
100             .getPassword(), persistenceUnit);
101         jpaBuilder.start();
102     }
103
104     /**
105      * Stops the tester. This must be called after the test.
106      */
107     public void stop() {
108         if (jpaBuilder != null) {
109             jpaBuilder.stop();
110         }
111         if (dbUtils != null) {
112             dbUtils.stop();
113         }
114         if (db != null) {
115             db.stop();
116         }
117     }
118
119     /**
120      * Gets the database.
121      * 
122      * @return Database.
123      */
124     public Database getDb() {
125         return db;
126     }
127
128     /**
129      * Gets the datasource.
130      * 
131      * @return Datasource.
132      */
133     public DataSource getDataSource() {
134         return dataSource;
135     }
136
137     /**
138      * Gets the database utilities.
139      * 
140      * @return Database utilities.
141      */
142     public DatabaseUtils getDbUtils() {
143         return dbUtils;
144     }
145
146     /**
147      * Gets the jpa builder.
148      * 
149      * @return JPA builder.
150      */
151     public JpaBuilder getJpaBuilder() {
152         return jpaBuilder;
153     }
154
155     /**
156      * Gets the persistence unit.
157      * 
158      * @return Persistence unit.
159      */
160     public PersistenceUnitDescription getPersistenceUnit() {
161         return persistenceUnit;
162     }
163
164 }