`

DBUnit入门

    博客分类:
  • Java
阅读更多
相信做过单元测试的人都会对JUnit非常的熟悉了,今天要介绍的DbUnit(http://dbunit.sourceforge.net/)则是专 门针对数据库测试的对JUnit的一个扩展,它可以将测试对象数据库置于一个测试轮回之间的状态。鉴于目前国内介绍DbUnit的系统教程比较少见,本文 将分从理论和实例两个方面带你领略DbUnit的精彩世界。

DbUnit设计理念
熟悉单元测试的开发人员都知道,在对数据库进行单元测试时候,通常采用的方案有运用模拟对象(mock objects)和stubs两种。通过隔离关联的数据库访问类,比如JDBC的相关操作类,来达到对数据库操作的模拟测试。然而某些特殊的系统,比如利 用了EJB的CMP(container-managed persistence)的系统,数据库的访问对象是在最底层而且很隐蔽的,那么这两种解决方案对这些系统就显得力不从心了。

DBUnit的设计理念就是在测试之前,备份数据库,然后给对象数据库植入我们需要的准备数据,最后,在测试完毕后,读入备份数据库,回溯到测试前的状态;
而且又因为DBUnit是对JUnit的一种扩展,开发人员可以通过创建测试用例代码,在这些测试用例的生命周期内来对数据库的操作结果进行比较。

DbUnit测试基本概念和流程
基于DbUnit 的测试的主要接口是IDataSet。IDataSet代表一个或多个表的数据。
可以将数据库模式的全部内容表示为单个IDataSet 实例。这些表本身由Itable 实例来表示。
IDataSet 的实现有很多,每一个都对应一个不同的数据源或加载机制。最常用的几种 IDataSet实现为:
FlatXmlDataSet:数据的简单平面文件 XML 表示
QueryDataSet:用 SQL 查询获得的数据
DatabaseDataSet:数据库表本身内容的一种表示
XlsDataSet :数据的excel表示

一般而言,使用DbUnit进行单元测试的流程如下:
1 根据业务,做好测试用的准备数据和预想结果数据,通常准备成xml格式文件。
2 在setUp()方法里边备份数据库中的关联表。
3 在setUp()方法里边读入准备数据。
4 对测试类的对应测试方法进行实装:执行对象方法,把数据库的实际执行结果和预想结果进行比较。
5 在tearDown()方法里边,把数据库还原到测试前状态。

DbUnit开发实例
下面通过一个实例来说明DbUnit的实际运用。

实例准备
比如有一个学生表[student],结构如下:
id char(4) pk 学号
name char(50) 姓名
sex char(1) 性别
birthday date 出生日期
准备数据如下:
id name sex birthday
0001 翁仔 m 1979-12-31
0002 王翠花 f 1982-08-09 测试对象类为StudentOpe.java,里边有2个方法:
findStudent(String id) :根据主键id找记录
addStudent(Student student) :添加一条记录

在测试addStudent方法时候,我们准备添加如下一条数据
id name sex birthday
0088 王耳朵 m 1982-01-01
那么在执行该方法后,数据库的student表里的数据是这样的:
id name sex birthday
0001 翁仔 m 1979-12-31
0002 王翠花 f 1982-08-09
0088 王耳朵 m 1982-01-01

然后我们说明如何对这2个方法进行单元测试。

实例展开
1 把准备数据和预想数据转换成xml文件
student_pre.xml
<?xml version='1.0' encoding="gb2312"?>
<dataset>
<student id="0001" name="翁仔" sex="m" birthday="1979-12-31"/>
<student id="0002" name="王翠花" sex="f" birthday="1982-08-09"/>
</dataset>

student_exp.xml
<?xml version='1.0' encoding="gb2312"?>
<dataset>
<student id="0001" name="翁仔" sex="m" birthday="1979-12-31"/>
<student id="0002" name="王翠花" sex="f" birthday="1982-08-09"/>
<student id="0088" name="王耳朵" sex="m" birthday="1982-01-01"/>
</dataset>

2 实装setUp方法,详细见代码注释。
protected void setUp() {
IDatabaseConnection connection =null;
try{
super.setUp();
//本例使用postgresql数据库
Class.forName("org.postgresql.Driver");
//连接DB
Connection conn=DriverManager.getConnection("jdbc:postgresql:testdb.test","postgres","postgres");
//获得DB连接
connection =new DatabaseConnection(conn);

//对数据库中的操作对象表student进行备份
QueryDataSet backupDataSet = new QueryDataSet(connection);
backupDataSet.addTable("student");
file=File.createTempFile("student_back",".xml");//备份文件
FlatXmlDataSet.write(backupDataSet,new FileOutputStream(file));

//准备数据的读入
IDataSet dataSet = new FlatXmlDataSet( new FileInputStream("student_pre.xml"));
DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);

}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(connection!=null) connection.close();
}catch(SQLException e){}
}
}
3 实装测试方法,详细见代码注释。

*检索类方法,可以利用assertEquals()方法,拿表的字段进行比较。
// findStudent
public void testFindStudent() throws Exception{
//执行findStudent方法
StudentOpe studentOpe=new StudentOpe();
Student result = studentOpe.findStudent("0001");

//预想结果和实际结果的比较
assertEquals("翁仔",result.getName());
assertEquals("m",result.getSex());
assertEquals("1979-12-31",result.getBirthDay());
}

*更新,添加,删除等方法,可以利用Assertion.assertEquals()方法,拿表的整体来比较。
public void testAddStudent() throws Exception{
//执行addStudent方法
StudentOpe studentOpe=new StudentOpe();
//被追加的记录
Student newStudent = new Student("0088","王耳朵","m","1982-01-01");
//执行追加方法
Student result = studentOpe.addStudent(newStudent);

//预想结果和实际结果的比较
IDatabaseConnection connection=null;

try{

//预期结果取得
IDataSet expectedDataSet = new FlatXmlDataSet(new FileInputStream("student_exp.xml"));
ITable expectedTable = expectedDataSet.getTable("student");

//实际结果取得
Connection conn=getConnection();
connection =new DatabaseConnection(conn);

IDataSet databaseDataSet = connection.createDataSet();
ITable actualTable = databaseDataSet.getTable("student");

//比较
Assertion.assertEquals(expectedTable, actualTable);

}finally{
if(connection!=null) connection.close();
}
}

*如果在整体比较表的时候,有个别字段不需要比较,可以用DefaultColumnFilter.excludedColumnsTable()方法,
将指定字段给排除在比较范围之外。比如上例中不需要比较birthday这个字段的话,那么可以如下代码所示进行处理:
ITable filteredExpectedTable = DefaultColumnFilter.excludedColumnsTable(expectedTable, new String[]{"birthday"});
ITable filteredActualTable = DefaultColumnFilter.excludedColumnsTable(actualTable,new String[]{"birthday"});
Assertion.assertEquals(filteredExpectedTable, filteredActualTable);

4 在tearDown()方法里边,把数据库还原到测试前状态
protected void tearDown() throws Exception{

IDatabaseConnection connection =null;
try{
super.tearDown();
Connection conn=getConnection();
connection =new DatabaseConnection(conn);

IDataSet dataSet = new FlatXmlDataSet(file);
DatabaseOperation.CLEAN_INSERT.execute(connection,dataSet);

}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(connection!=null) connection.close();
}catch(SQLException e){}
}

}

最后
无疑,使用DbUnit能够极大的提高数据库测试的效率,希望通过本文能够让您掌握这一数据库测试的利器
分享到:
评论

相关推荐

    dbunit入门实例

    dbunit入门实例 dbunit入门实例 dbunit入门实例 dbunit入门实例

    dbunit-2.4.7所有jar以及dbunit入门教程

    最新的最全的dbunit jar包以及入门教程

    DbUnit入门实战

    DbUnit入门实战 摘自:http://blog.csdn.net/yuezu1026/archive/2009/04/08/4055923.aspx

    dbunit使用实例

    用dbunit的两个例子,很不错,有帮助

    单元测试JUnit4和DbUnit

    单元测试入门学习,和dbunit结合开发

    PHP / PHPUnit的DbUnit端口。-PHP开发

    PHPUnit下载入门我们分发了一个PHP存档(PHAR),其中包含使用PHPUnit所需的一切。 只需从此处下载它,使其可执行,然后将其放入$ PATH中,例如:➜&nbs此扩展不再维护用于数据库交互测试的DbUnit PHPUnit扩展。 ...

    spring-test-dbunit-example

    快速入门示例Spring DBUnit提供了Spring测试框架和DBUnit项目之间的集成。 在这个例子中,我们展示了如何使用Hypersonic内存数据库测试Hibernate JPA项目。依存关系该项目将使用Apache Maven构建。 这是完整的POM...

    junit和TestNG框架入门

    本文介绍和对比了TestNG和junit框架,并举出实例说明。 同时讲解了Mockito和Dbunit框架的使用

    Appfuse教程Appfuse开发.pdf

    Appfuse是由Matt Raible开发的一个指导性的入门级J2EE框架,它对如何集成流行的Spring、Hibernate、iBatis、struts、Xdoclet、junit 等基础框架给出了示范。提供了对Taperstry和JSF的支持。  AppFuse是一个集成了...

    通向架构师的道路

    自己整理的一位牛人写的通向架构师的道路的博文,对架构师入门很有指导意义,列出章节如下: (第一天)之Apache整合Tomcat (第二天)之apache tomcat https应用 (第三天)之apache性能调优 (第四天)之Tomcat...

    Exam:Concordion BDD框架扩展

    在后台广泛使用的一组测试工具: dbunit, reset -assured,xml-unit,json-unit 入门 1)安装 玛文 &lt; groupId&gt;io.github.adven27 &lt; artifactId&gt;exam-ms &lt; version&gt;5.0.0 Gradle testCompile " io.github....

    Spring.3.x企业应用开发实战(完整版).part2

    第2章 快速入门 2.1 实例功能概述 2.1.1 比Hello World更适用的实例 2.1.2 实例功能简介 2.2 环境准备 2.2.1 创建库表 2.2.2 建立工程 2.2.3 类包及Spring配置文件规划 2.3 持久层 2.3.1 建立领域对象 2.3.2 UserDao...

    Spring3.x企业应用开发实战(完整版) part1

    第2章 快速入门 2.1 实例功能概述 2.1.1 比Hello World更适用的实例 2.1.2 实例功能简介 2.2 环境准备 2.2.1 创建库表 2.2.2 建立工程 2.2.3 类包及Spring配置文件规划 2.3 持久层 2.3.1 建立领域对象 2.3.2 UserDao...

Global site tag (gtag.js) - Google Analytics