Java tutorial
/* * Copyright 2008-2012 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 almira.sample.dao; import static org.junit.Assert.assertNotNull; import java.io.InputStream; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import javax.annotation.PostConstruct; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.sql.DataSource; import org.dbunit.Assertion; import org.dbunit.DataSourceDatabaseTester; import org.dbunit.IDatabaseTester; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.ReplacementDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.operation.DatabaseOperation; import org.hibernate.search.jpa.FullTextEntityManager; import org.hibernate.search.jpa.Search; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.transaction.AfterTransaction; import org.springframework.test.context.transaction.BeforeTransaction; /** * Inspired from [Tahchiev11] page 351, but using Unitils annotations. * * See also: http://jroller.com/aalmiray/entry/dbunit_using_the_idatabasetester * * The database is cleared after each transaction, you can change this behaviour * by overriding <code>cleanUpDatabase()</code>. * * Make sure you don't specify any IDs in the dataSets when using primary keys * defined as IDENTITY (http://db.apache.org/derby/docs/10.1/ref/rrefsqlj37836.html). * * Also make sure you set the version column when using optimistic locking. * * @author 'Daniel TISCHER' * */ @ContextConfiguration(locations = { "classpath:/testApplicationContext.xml" }) @RunWith(SpringDbUnitClassRunner.class) public abstract class AbstractSpringDbUnitTestCase implements DataSetContext { private static final Logger LOG = Logger.getLogger(AbstractSpringDbUnitTestCase.class.getName()); @PersistenceContext private EntityManager em; // used to index database with Hibernate Search @Inject private DataSource dataSource; // JDBC dataSource used by DBUnit @PostConstruct private void init() { dbTester = new DataSourceDatabaseTester(dataSource); } private IDatabaseTester dbTester; private String dataSetName = null; private String expectedDataSetName = null; private HashMap<String, String> replacementObjects = new HashMap<String, String>(); @Override public void setDataSetName(String dataSetName) { this.dataSetName = dataSetName; } @Override public void setExpectedDataSetName(String expectedDataSetName) { this.expectedDataSetName = expectedDataSetName; } public void addReplacementObject(String key, String value) { replacementObjects.put(key, value); } public void addReplacementObject(String key, Long value) { replacementObjects.put(key, value.toString()); } public void addReplacementObject(String key, Date value) { SimpleDateFormat df = new SimpleDateFormat(getDateFormatString()); replacementObjects.put(key, df.format(value)); } // http://bugs.mysql.com/bug.php?id=8523 // http://stackoverflow.com/questions/2572209/why-doesnt-mysql-support-millisecond-microsecond-precision private String getDateFormatString() { String driver = ""; try { driver = dataSource.getConnection().getMetaData().getDatabaseProductName(); } catch (SQLException ignore) { } boolean isMysql = "MySQL".equals(driver); return "yyyy-MM-dd HH:mm:ss" + (isMysql ? "" : ".SSS"); } @BeforeTransaction public void setupDataSet() throws InterruptedException { if (dataSetName != null) { LOG.info("Inserting dataset " + dataSetName); try { dbTester.setDataSet(getNullReplacedDataSet(dataSetName)); dbTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT); dbTester.onSetup(); indexDatabaseForHibernateSearch(); } catch (Exception e) { throw new RuntimeException("Exception inserting dataSet " + dataSetName, e); } } } private void indexDatabaseForHibernateSearch() throws InterruptedException { FullTextEntityManager ftem = Search.getFullTextEntityManager(em); ftem.createIndexer().startAndWait(); } @AfterTransaction public void assertDataSetAndCleanUp() throws Exception { try { assertDataSet(); } finally { cleanUpDatabase(); } } private void assertDataSet() { if (expectedDataSetName != null) { try { LOG.info("Asserting dataset " + expectedDataSetName); IDataSet expectedDataSet = getReplacedDataSet(expectedDataSetName, replacementObjects); IDatabaseConnection connection = dbTester.getConnection(); // http://dbunit.sourceforge.net/faq.html#typefactory // DatabaseConfig config = connection.getConfig(); // config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory()); IDataSet actualDataSet = connection.createDataSet(); Assertion.assertEquals(expectedDataSet, actualDataSet); } catch (Exception e) { throw new RuntimeException("Exception asserting dataSet " + expectedDataSetName, e); } } } protected void cleanUpDatabase() throws Exception { LOG.info("Calling DELETE_ALL on database"); dbTester.setTearDownOperation(DatabaseOperation.DELETE_ALL); dbTester.onTearDown(); } private IDataSet getReplacedDataSet(String dataSetFileName, Map<String, String> replacementObjects) throws Exception { ReplacementDataSet replacementDataSet = (ReplacementDataSet) getNullReplacedDataSet(dataSetFileName); if (replacementObjects != null && !replacementObjects.isEmpty()) { for (Map.Entry<String, String> e : replacementObjects.entrySet()) { replacementDataSet.addReplacementObject(e.getKey(), e.getValue()); LOG.info("ReplacementObject registered " + e.getKey() + "=" + e.getValue()); } } return replacementDataSet; } private IDataSet getNullReplacedDataSet(String dataSetFileName) throws DataSetException { FlatXmlDataSet dataSet = getDataSet(dataSetFileName); ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet); replacementDataSet.addReplacementObject("[NULL]", null); return replacementDataSet; } private FlatXmlDataSet getDataSet(String dataSetFileName) throws DataSetException { InputStream inputStream = SpringDbUnitClassRunner.class.getResourceAsStream(dataSetFileName); assertNotNull("File " + dataSetFileName + " not found in the same package as test class", inputStream); return new FlatXmlDataSetBuilder().build(inputStream); } }