/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wamblee.support.persistence;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.dbunit.IDatabaseTester;
import org.wamblee.support.jndi.StubInitialContextFactory;
/**
* This class is the entry point for JPA tests. Test code should construct a
* JpaTester in the @Before
method and call {@link #start()} on it
* in that method. Also, test code should call {@link #stop()} on it in the
* @After
method.
*
* This class is constructed with a description of the persistence unit to be
* tested. The principle is that an existing persistence.xml
can be
* tested without change in unit test code.
*
* It then takes care of the following:
*
JpaTester
*
* NOTE: Persistence XML files should be explicitly configured with the classes
* that are part of the persistence unit since scanning of classes does not work
* correctly in a unit test environment. This is currently the only limitation.
*/
public class JpaTester {
private PersistenceUnitDescription persistenceUnit;
private Database db;
private DataSource dataSource;
private DatabaseUtils dbUtils;
private JpaBuilder jpaBuilder;
private IDatabaseTester dbTester;
/**
* Constructs the tester.
*
* @param aPersistenceUnit
* Persistence unit under test.
*/
public JpaTester(PersistenceUnitDescription aPersistenceUnit) {
persistenceUnit = aPersistenceUnit;
}
/**
* Starts the tester. This must be called prior to running the test.
*
* @throws Exception
*/
public void start() throws Exception {
db = DatabaseBuilder.getDatabase();
dataSource = db.start();
// NOTE: adding datasource to JNDI is no longer needed for
// JPA testing, but is nice to have available for other uses.
StubInitialContextFactory.register();
try {
InitialContext ctx = new InitialContext();
ctx.bind(persistenceUnit.getJndiName(), dataSource);
} catch (NamingException e) {
throw new RuntimeException("JNDI problem", e);
}
dbUtils = new DatabaseUtils(dataSource, persistenceUnit.getTables());
dbUtils.start();
dbUtils.dropTables();
dbUtils.dropTables(JpaCustomizerBuilder.getCustomizer().getJpaTables());
jpaBuilder = new JpaBuilder(db.getJdbcUrl(), db.getUsername(), db.getPassword(), persistenceUnit);
jpaBuilder.start();
// db tester should be created after Jpa builder because jpa builder
// creates the
// tables that the tester looks at when it is initialized.
dbTester = dbUtils.createDbTester();
}
/**
* Stops the tester. This must be called after the test.
*/
public void stop() {
if (jpaBuilder != null) {
jpaBuilder.stop();
}
if (dbUtils != null) {
dbUtils.stop();
}
if (db != null) {
db.stop();
}
}
public Database getDb() {
return db;
}
public DataSource getDataSource() {
return dataSource;
}
public IDatabaseTester getDbTester() {
return dbTester;
}
public DatabaseUtils getDbUtils() {
return dbUtils;
}
public JpaBuilder getJpaBuilder() {
return jpaBuilder;
}
public PersistenceUnitDescription getPersistenceUnit() {
return persistenceUnit;
}
}