让DbUnit加入你的单元测试

 

开始

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()));

 

  

 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值