讓DbUnit加入你的單元測試

 

開始

1.    DBTestCase的子類建立數據庫

2.    用你自己的TestCase子類建立數據庫

3.    數據庫數據校驗

4.    DbUnitAnt任務和Canoo web測試(此處省略,另詳)

 

DBTestCase的子類建立數據庫

 

第一步:創建你的dataset文件

你的測試需要一些數據。這就意味着你必須創建dataset。許多情況下你都是處理xmldataset。你可以人工湊一些一般的xml dataset或是從你的數據庫中導出一個xml dataset.

 

第二步:繼承DBTestCase

現在你要創建一個測試類。最簡單的方式是用通過繼承DbUnitDBTestCase來創建你自己的測試類。DBTestCase繼承了JunitTestCase類。一個模板方法你需要實現,getDataSet()返回你在第一步創建的datasetDBTestCase依靠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類。你可以覆蓋標準的JunitSetUp()方法,執行你所需要的數據庫操作。如果你要執行清除,同樣覆蓋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()));

 

  

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章