package at.ac.tuwien.sepm.assignment.groupphase.util; import static org.dbunit.Assertion.assertEquals; import java.io.InputStream; import java.lang.invoke.MethodHandles; import java.sql.SQLException; import java.sql.Types; import java.util.Collection; import java.util.Collections; import org.dbunit.DefaultDatabaseTester; import org.dbunit.IDatabaseTester; import org.dbunit.IOperationListener; import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.datatype.DataType; import org.dbunit.dataset.datatype.DataTypeException; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.ext.h2.H2DataTypeFactory; import org.dbunit.operation.DatabaseOperation; import org.junit.After; import org.junit.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component public abstract class JdbcTestCase { private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static final String JDBC_URL = "jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'classpath:sql/database.sql'"; private IDatabaseTester dbTester; private IDatabaseConnection connection; private IOperationListener operationListener; private JDBCConnectionManager jdbcConnectionManager; protected JdbcTestCase() { jdbcConnectionManager = new JDBCConnectionManager(JDBC_URL); } protected abstract IDataSet getDataSet() throws Exception; protected IDataSet getDataSet(String xmlname) throws DataSetException { InputStream res = getClass().getClassLoader().getResourceAsStream(xmlname); FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); builder.setColumnSensing(true); return builder.build(res); } protected JDBCConnectionManager getJdbcConnectionManager() { return jdbcConnectionManager; } protected IDatabaseConnection getConnection() throws Exception { if (connection == null) connection = new DatabaseConnection(jdbcConnectionManager.getConnection(), null, true); return connection; } private IOperationListener getOperationListener() { if (operationListener == null) { operationListener = new IOperationListener() { @Override public void connectionRetrieved(IDatabaseConnection connection) { setUpDatabaseConfig(connection.getConfig()); } @Override public void operationSetUpFinished(IDatabaseConnection connection) { LOG.debug("operationSetUpFinished(connection={}) - start", connection); } @Override public void operationTearDownFinished(IDatabaseConnection connection) { LOG.debug( "operationTearDownFinished(connection={}) - start", connection); try { connection.close(); } catch (SQLException e) { LOG.error("Failed to close connection:" + e); e.printStackTrace(); } } }; } return operationListener; } // override DBUnit's enum handling private void setUpDatabaseConfig(DatabaseConfig config) { H2DataTypeFactory factory = new H2DataTypeFactory() { boolean isEnumType(String sqlTypeName) { return sqlTypeName.equalsIgnoreCase("enum"); } boolean isTimestampWithTimeZoneType(String sqlTypeName) { return sqlTypeName.equalsIgnoreCase("timestamp with time zone"); } @Override public DataType createDataType(int sqlType, String sqlTypeName) throws DataTypeException { if (isEnumType(sqlTypeName)) { sqlType = Types.VARCHAR; } else if (isTimestampWithTimeZoneType(sqlTypeName)) { sqlType = Types.VARCHAR; } return super.createDataType(sqlType, sqlTypeName); } @Override public Collection getValidDbProducts() { return Collections.singletonList("H2"); } }; config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, factory); } protected void compareWith(String xmlname, String[] tables) throws Exception { InputStream res = getClass().getClassLoader().getResourceAsStream(xmlname); IDataSet actual = getConnection().createDataSet(); IDataSet expected = new FlatXmlDataSetBuilder().build(res); for (String table : tables) { assertEquals(expected.getTable(table), actual.getTable(table)); } } @Before public void setUp() throws Exception { IDataSet dataSet = getDataSet(); dbTester = new DefaultDatabaseTester(getConnection()); getOperationListener().connectionRetrieved(getConnection()); dbTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT); dbTester.setTearDownOperation(DatabaseOperation.REFRESH); dbTester.setDataSet(dataSet); dbTester.setOperationListener(getOperationListener()); dbTester.onSetup(); } @After public void tearDown() throws Exception { try { dbTester.onTearDown(); getConnection().close(); } finally { dbTester = null; } } }