工作时写服务和后台,在项目代码写完之后,当然就是单元测试了,在用JUnit时发现在测很多service层方法时,直接掉用了Dao层的方法,这样感觉不大合理。直接写JDBC又比较麻烦,ConnectManager-->Connection-->PreparedStatement-->ResultSet.这样下来很繁杂。所以在网上找了很多资料,无意间了解到了DBUnit,觉得非常强大。所以就学习了一下,算是入一下门,顺便将原文转载过来,以备今后查阅,同时也希望能帮助到大家!
——————————————————————————————————————————————————————
相信做过单元测试的人都会对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能够极大的提高数据库测试的效率,希望通过本文能够让您掌握这一数据库测试的利器
(转自:http://www.blogjava.net/liuzheng/articles/190128.html)
分享到:
相关推荐
dbunit入门实例 dbunit入门实例 dbunit入门实例 dbunit入门实例
最新的最全的dbunit jar包以及入门教程
Junit,dbunit单元测试jar包
DbUnit入门实战 摘自:http://blog.csdn.net/yuezu1026/archive/2009/04/08/4055923.aspx
单元测试入门学习,和dbunit结合开发
几乎包含了所有junit所要用到的扩展包
dbUnit is a JUnit extension targeted for database-driven projects that, among other things, puts your database into a known state between test runs. Last Updated: 2015-09-07
用dbunit的两个例子,很不错,有帮助
DbUnit is a JUnit extension (also usable with Ant) targeted for database-driven projects that, among other things, puts your database into a known state between test runs. This is an excellent way to ...
DbUnit is a JUnit extension (also usable with Ant) targeted at database-driven projects that, among other things, puts your database into a known state between test runs. This is an excellent way to ...
DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类DBUNIT 基类...
dbunit-2.4.9 hamcrest-core-1.3 hamcrest-library-1.3 junit-4.12 slf4j-api-1.6.1 slf4j-log4j12-1.6.1 log4j-1.2.15
引言一个简单的例子JUnit安装与运行JUnit常见问题设计目标设计内容模仿对象测试DbUnit使用JUNIT用JUnit编写一个简单的测试,可以有三个简单步骤
dbunit是一个基于junit扩展的数据库测试框架。 更多资源详见: http://blog.csdn.net/fanxiaobin577328725/article/details/51894331 (包含图书各部分和随书源码,还有其它资源的详细下载地址)
包含junit-4.11.jar, dbunit-2.4.9.jar, unitils-3.3-with-dependencies.zip, mockito-1.9.5.zip
dbunit使用必需Jar包,总共4个必需Jar包
改代码是我的我的一个项目自己写完后自测所以就写了这个junit的单元测试类,以及可能会遇到的一些问题,以及其中的一些经验,项目用的是spring + mybatis。我写的这个测试类基本概括了单元测试的基本用法,只要按照...
dbunit-2.4.9 源码 http://www.dbunit.org/apidocs/index.html 代码 API
DBUNIT使用的详细文档
本文介绍和对比了TestNG和junit框架,并举出实例说明。 同时讲解了Mockito和Dbunit框架的使用