開始
1. 用DBTestCase的子類建立數據庫
2. 用你自己的TestCase子類建立數據庫
3. 數據庫數據校驗
4. DbUnit的Ant任務和Canoo web測試(此處省略,另詳)
用DBTestCase的子類建立數據庫
第一步:創建你的dataset文件
你的測試需要一些數據。這就意味著你必須創建dataset。許多情況下你都是處理xml的dataset。你可以人工湊一些一般的xml dataset或是從你的數據庫中導出一個xml dataset.
第二步:繼承DBTestCase類
現在你要創建一個測試類。最簡單的方式是用通過繼承DbUnit的DBTestCase來創建你自己的測試類。DBTestCase繼承了Junit的TestCase類。一個模板方法你需要實現,getDataSet()返回你在第一步創建的dataset。DBTestCase依靠IdatabaseTester來工作,默認的配置是使用PropertiesBaseJdbcDatabaseTester,它是用系統屬性來指出DriverManager的配置。最簡單的方式是在你測試類的構造函數中配置它。你可以通過覆蓋getDatabaseTester()方法來修改它的行為。
使用下面提供的三種IDatabaseTester之一實現,你也可以使用下面表中描述的DBTestCase的其它子類。
JdbcBaseDBTestCase
|
使用DriverManager來創建連接(在JdbcDatabaseTester的幫助下)
|
DataSourceBasedDBTestCase
|
使用javax.sql.DataSource來創建連接(在DataSourceDatabaseTester的幫助下)
|
JndiBasedDBTestCase
|
使用javax.sql.DataSourece通過JNDI定位(在jndiDatabaseTester的幫助下)
|
下面是一個簡單的實現,連接到一個Hypersonic數據庫并返回xml dataset:
public class SampleTest extends DBTestCase
{
public SampleTest(String name)
{
super( name );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_DRIVER_CLASS, "org.hsqldb.jdbcDriver" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_CONNECTION_URL, "jdbc:hsqldb:sample" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_USERNAME, "sa" );
System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_PASSWORD, "" );
// System.setProperty( PropertiesBasedJdbcDatabaseTester.DBUNIT_SCHEMA, "" );
}
protected IDataSet getDataSet() throws Exception
{
return new FlatXmlDataSet(new FileInputStream("dataset.xml"));
}
}
第三步:(可選)實現getSetUpOperation()和getTearDownOperation()方法
默認的情況,DbUnit在每次執行test之前執行一個CLEAN_INSERT操作并且不之后不執行清除操作。你可以通過覆蓋getSetUpOperation()和getTearDownOperation()來改變這個行為。
下面這個例子演示你可以通過簡單的覆蓋方法改變執行測試前和后。
public class SampleTest extends DBTestCase
{

protected DatabaseOperation getSetUpOperation() throws Exception
{
return DatabaseOperation.REFRESH;
}
protected DatabaseOperation getTearDownOperation() throws Exception
{
return DatabaseOperation.NONE;
}

}
第四步:實現你的testXXX()方法
就像你使用JUit一樣實現test方法。你的數據庫在測試方法之前初始化并且在測試之后清除,這取決于你在前幾步是怎么做的。
用你自己的TestCase子類建立數據庫
為了使用DbUnit你不是必須要繼承DBTestCase類。你可以覆蓋標準的Junit的SetUp()方法,執行你所需要的數據庫操作。如果你要執行清除,同樣覆蓋teardown()方法。
例如:
public class SampleTest extends TestCase
{
public SampleTest(String name)
{
super(name);
}
protected void setUp() throws Exception
{
super.setUp();
// initialize your database connection here
IDatabaseConnection connection = null;
// 
// initialize your dataset here
IDataSet dataSet = null;
// 
try1
{
DatabaseOperation.CLEAN_INSERT.execute(connection, dataSet);
}
finally
{
connection.close();
}
}

}
自從2.2版本你可以使用IdatabaseTester來完成同樣的功能。就像前面所提到過的,DBTestCase內部是使用IdatabaseTester來實現的。你的測試類可以使用這個功能操作數據集(DataSets)。目前有4個方便的實現。
JdbcDatabaseTester
|
使用DriverManager來創建連接。
|
PropertiesBasedJdbcDatabaseTester
|
也是使用DriverManager來創建連接,但是配置信息是從系統屬性中讀取的。這是DBTestCase的默認實現方式。
|
DataSourceDatabaseTester
|
使用javax.sql.DataSource創建連接。
|
JndiDatabaseTester
|
使用javax.sql.DataSource通過JNDI尋找
|
你也可以提供你自己的IdatabaseTester實現,推薦使用AbstractDatabaseTester作為一個開始點。
例:
public class SampleTest extends TestCase
{
private IDatabaseTester databaseTester;
public SampleTest(String name)
{
super(name);
}
protected void setUp() throws Exception
{
databaseTester = new JdbcDatabaseTester("org.hsqldb.jdbcDriver",
"jdbc:hsqldb:sample", "sa", "");
// initialize your dataset here
IDataSet dataSet = null;
// 
databaseTester.setDataSet( dataSet );
// will call default setUpOperation
databaseTester.onSetUp();
}
protected void tearDown() throws Exception
{
// will call default tearDownOperation
databaseTester.onTearDown();
}

}
數據庫數據校驗
DbUnit提供校驗兩個表或是數據集是否包含相同的數據的方法。下面的兩個方法是在執行測試類的時候可以校驗你的數據庫中是否包含預期的數據。
public class Assertion
{
public static void assertEquals(ITable expected, ITable actual)
public static void assertEquals(IDataSet expected, IDataSet actual)
}
例子
以下例子,展示怎么比較一個數據庫表的快照和一個XML表。
public class SampleTest extends DBTestCase
{
public SampleTest(String name)
{
super(name);
}
// Implements required setup methods here

public void testMe() throws Exception
{
// Execute the tested code that modify the database here

// Fetch database data after executing your code
IDataSet databaseDataSet = getConnection().createDataSet();
ITable actualTable = databaseDataSet.getTable("TABLE_NAME");
// Load expected data from an XML dataset
IDataSet expectedDataSet = new FlatXmlDataSet(new File("expectedDataSet.xml"));
ITable expectedTable = expectedDataSet.getTable("TABLE_NAME");
// Assert actual database table match expected table
Assertion.assertEquals(expectedTable, actualTable);
}
}
actual數據集是一個數據庫的快照可以和你想要比較的expected數據集進行比較。就象他的名字一樣,expected數據集中包含預期的值。
expected數據集一定要和你建立數據庫時的對象不一樣。因為你需要兩個數據集,一個是在測試之前建立數據庫,一個是提供匹配測試時的expected數據。
使用查詢來獲取數據庫的快照
你也可以校驗查詢的結果是不是和期望的數據集匹配。這個查詢可以使查詢一個表中的一部分也可以是多表的聯合查詢。
Itable actualJoinData = getConnection().createQueryTable("RESULT_NAME",
"SELECT * FROM TABLE1, TABLE2 WHERE
");
在比較的時候忽略一些列
有些時候希望忽視一些列來進行比較,特別是對主鍵,日期或是時間列,這些列的值是在測試的時候又代碼產生的。一種方式是在你的expected表中省略你不想比較的列的聲明。這樣你可以過濾真實的數據庫表只暴露出expected表中的列。
下面這些代碼片段向你展示怎么過濾真實數據庫中的表。首先,真實數據庫中必須包含expected表中的所有列。另外,真實表中有這些列而expected表中沒有這些列,這種情況是允許的。
ITable filteredTable = DefaultColumnFilter.includedColumnsTable(actual,
expected.getTableMetaData().getColumns());
Assertion.assertEquals(expected, filteredTable);
這個技術的主要限制是你不能在你的expected數據集XML中使用DTD。使用DTD的話你需要過濾expected表和真實表中的列。查看FAQ中關于在運行時排除一些表的列(excluding some table columns at runtime)。
行順序
默認的情況下,用DbUnit得到的數據庫快照表是按主鍵排序的。如果一個表沒有主鍵或是主鍵是由數據庫自動產生的,行的順序是不確定的,那么assertEquals將會失敗。
你一定要排序你的數據庫快照通過在IdatabaseConnection.createQueryTable時手工加入”ORDER BY”語句。或者你可以這樣使用SortedTable:
Assertion.assertEquals(new SortedTable(expected),
new SortedTable(actual, expected.getTableMetaData()));