The below class has three key methods:
- initEntityManager() - this method is annotated with @BeforeClass so will only be called once for this test and called before any tests are run. The method will create an entity manager, get a connection to an instance of the in memory Java database HSQL and then populate it by reading in the flat xml database record structure that is contained in the file test-dataset.xml. For alternative dataset formats please visit http://www.dbunit.org/apidocs/org/dbunit/dataset/IDataSet.html
- closeEntityManager() - this method is annotated with @AfterClass so will only be called once for this test and called after all the tests have been run. The method will close down the entity manager and the entity manager connection factory.
- cleanDB() - this method is annotated with @Before and will be called before every test method call. The call to DatabaseOperation.CLEAN_INSERT.execute will clean the database tables and insert the records from the dataset xml file. Database operations other than CLEAN_INSERT are described below:
INSERT inserts the data in the dataset into the database.
DELETE deletes only the data in the dataset from the database.
DELETE_ALL deletes all rows of tables present in the specified dataset.
TRUNCATE truncate tables listed in the dataset.
REFRESH refreshes the database using the data in the dataset.
NONE does what it says, nothing.
import org.dbunit.database.DatabaseConfig; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; import org.dbunit.ext.hsqldb.HsqldbDataTypeFactory; import org.dbunit.operation.DatabaseOperation; import org.hibernate.impl.SessionImpl; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import org.junit.Test; public class JPATest { protected static EntityManagerFactory entityManagerFactory; protected static EntityManager entityManager; protected static IDatabaseConnection connection; protected static IDataSet dataset; @BeforeClass public static void initEntityManager() throws Exception { entityManagerFactory = Persistence.createEntityManagerFactory("PersistenceUnit"); entityManager = entityManagerFactory.createEntityManager(); connection = new DatabaseConnection(((SessionImpl)(entityManager.getDelegate())).connection()); connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new HsqldbDataTypeFactory()); FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder(); flatXmlDataSetBuilder.setColumnSensing(true); dataset = flatXmlDataSetBuilder.build( Thread.currentThread().getContextClassLoader().getResourceAsStream("test-dataset.xml")); } @AfterClass public static void closeEntityManager() { entityManager.close(); entityManagerFactory.close(); } @Before public void cleanDB() throws Exception { DatabaseOperation.CLEAN_INSERT.execute(connection, dataset); } @Test public void testAUsefulMethod() throws Exception { // .... test code } }
An example structure of the dataset.xml is shown below:
<?xml version='1.0' encoding='UTF-8'?> <dataset> <customer id="1" surname="SURNAME" firstName="FIRSTNAME" middleName="MIDDLENAME" personalAccount="true"/> <customer id="2" surname="SURNAME" firstName="FIRSTNAME" personalAccount="true" balance="100000.00/> </dataset>
One point of note is that when deleting database records using DBUnit the same rules apply as if you were using SQL. You will not be able to delete a record if its primary key is a foreign key on another table. An example in Flat XML for a Customer class that has many Addresses would be:
<?xml version='1.0' encoding='UTF-8'?> <dataset> <customer/> <address/> <customer_address/> </dataset>
Finally, there are many useful methods on IDataSet and ITable interfaces. An example being to obtain the number of records of a particular table:
int customerRecordCount = dataset.getTable("Customer").getRowCount();