DBUnit is very nice for testing database content changes made by an application. You define in XML the data including the structure of your tables (dataset.xml).
Simple_Data is the name of the table and each column is a attribute in the xml doc with the content value e.g. id with value 1.
The Getting Started of DBUnit work with JUnit 3.8 and self handling of the JDBC Connection.
JUnit 4.x are more comfortable with annotations based test methods and Spring comes with dependency injection for separating
configuration from implementation code.
The following approach combines DBUnit with JUnit 4.4 and Spring 2.5.6 to test comfortable a Oracle 10g database.
I use Maven 2.x to define the depending libraries used by the example (pom.xml):
4.0.0 de.schaeftlein.dev.dbunit test-dbunit test-dbunit 0.0.1-SNAPSHOT org.dbunit dbunit 2.4.2 org.springframework spring 2.5.6 jar compile junit junit 4.4 commons-dbcp commons-dbcp 1.2.2 org.springframework spring-test 2.5.6 org.slf4j slf4j-api 1.5.6 org.slf4j log4j-over-slf4j 1.5.6 log4j log4j 1.2.14 org.slf4j slf4j-log4j12 1.5.6 com.oracle ojdbc14 10.2.0.2.0
Keep in mind that the Oracle JDBC Driver has to be downloaded manually.
The public maven repos include only the Pom definition for the oracle driver. Generate with maven command line tool the eclipse project files:
mvn clean eclipse:clean eclipse:eclipse
The JDBC datasource is defined via Spring (applicationContext.xml):
Additionally we define the expected data as well in XML for DBUnit (expectedDataSet.xml):
Now we can code our JUnit 4.x Test to
- load data before the test method
- change the data via JDBC to emulate a application
- compare the changed data with expected data
- clean up the database
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:applicationContext.xml"}) public class TestDBUnitWithSpring { @Autowired private DataSource dataSource; @Before public void init() throws Exception{ // insert data into db DatabaseOperation.CLEAN_INSERT.execute(getConnection(), getDataSet()); } @After public void after() throws Exception{ // insert data into db DatabaseOperation.DELETE_ALL.execute(getConnection(), getDataSet()); } private IDatabaseConnection getConnection() throws Exception{ // get connection Connection con = dataSource.getConnection(); DatabaseMetaData databaseMetaData = con.getMetaData(); // oracle schema name is the user name IDatabaseConnection connection = new DatabaseConnection(con,databaseMetaData.getUserName().toUpperCase()); DatabaseConfig config = connection.getConfig(); // oracle 10g config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new Oracle10DataTypeFactory()); // receycle bin config.setFeature(DatabaseConfig.FEATURE_SKIP_ORACLE_RECYCLEBIN_TABLES, Boolean.TRUE); return connection; } private IDataSet getDataSet() throws Exception{ // get insert data File file = new File("src/test/resources/dataset.xml"); return new FlatXmlDataSet(file); } @Test public void testSQLUpdate() throws Exception{ Connection con = dataSource.getConnection(); Statement stmt = con.createStatement(); // get current data ResultSet rst = stmt.executeQuery("select * from simple_data where id = 1"); if(rst.next()){ // from dataset.xml assertEquals("value_before", rst.getString("content")); rst.close(); // update via sql int count = stmt.executeUpdate("update simple_data set content='value_after' where id=1"); stmt.close(); con.close(); // expect only one row to be updated assertEquals("one row should be updated", 1, count); // Fetch database data after executing the code QueryDataSet databaseSet = new QueryDataSet(getConnection()); // filter data databaseSet.addTable("simple_data", "select * from simple_data where id = 1"); ITable actualTable = databaseSet.getTables()[0]; // Load expected data from an XML dataset IDataSet expectedDataSet = new FlatXmlDataSet(new File("src/test/resources/expectedDataSet.xml")); ITable expectedTable = expectedDataSet.getTable("simple_data"); // filter unnecessary columns of current data by xml definition actualTable = DefaultColumnFilter.includedColumnsTable(actualTable, expectedTable.getTableMetaData().getColumns()); // Assert actual database table match expected table assertEquals(1,expectedTable.getRowCount()); assertEquals(expectedTable.getRowCount(), actualTable.getRowCount()); assertEquals(expectedTable.getValue(0, "content"), actualTable.getValue(0, "content")); } else { fail("no rows"); rst.close(); stmt.close(); con.close(); } } }