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

上面一节中我们使用了hashmap来模拟操作真正的数据库,这一章中我们可以使用dbunit工具来测试数据库的操作

第一步我们首先下载对应的jar包

需要上面的两个jar包

第二步在src目录下创建xml文件,xml文件的名字要和测试的数据库中的表名一样 t_user.xml

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<t_user id ="1" username="admin" password="123" nickname="超级管理员"/> </dataset>

也可以采用下面的方式创建

二者却别在于使用的DataSet不一样,xml方式使用的是XmlDataSet,上面第一种方式使用的是FlatXmlDataSet

第三步:创建dbunit的conncetion

依赖上面章节中DButils中创建的connection

DatabaseOperation.UPDATE:这个操作将从测试数据源中读取的数据集的内容更新到数据库中,注意这个操作正确执行的前提是测试数据表已经存在,如果不存在这个测试用例将会失败

DatabaseOperation.INSERT:这个操作把从测试数据源中读取的数据集的内容插入到数据库中,注意这个操作正确执行的前提是测试数据表不存在,这个操作将新建数据表。如果测试数据表已经存在这个测试用例将会失败。另外,在执行这个操作的时候要特别注意数据集中数据表的顺序,否则可能会因为违反外键约束而造成测试用例失败

DatabaseOperation.DELETE:这个操作会从数据库中删除数据,注意,这个操作只删除数据集中存在的数据行而不是整个数据表中的数据

DatabaseOperation.DELETE_ALL:这个操作删除数据表中的所有行,注意,这个操作也只影响数据集中声明了的数据表,数据集中没有涉及到的数据表中的数据不会删除

DatabaseOperation.TRUNCATE:这个操作将删除数据集中声明的数据表,如果数据中有些表并没有在预定义的数据集中提到,这个数据表将不会被影响。注意,这个操作是按照相反的顺序执行的

DatabaseOperation.REFRESH:顾名思义,这个操作将把预定义数据集中的数据同步到数据库中,也就是说这个操作将更新数据数中已有的数据、插入数据库中没有的数据。数据库中已有的、但是数据集中没有的行将不会被影响。我们用一个产品数据库的拷贝进行测试的时候可以使用这个操作将预定义数据同步到产品数据库中

DatabaseOperation.CLEAN_INSERT:删除所有的数据表中的数据,然后插入数据集中定义的数据,如果你想保证数据库是受控的,这个你会比较喜欢。

DatabaseOperation.NONE:不执行任何操作

CompositeOperation:将多个操作组合成一个,便以维护和重用

TransactionOperation:在一个事物内执行多个操作

IdentityInsertOperation:在使用MSSQL的时候,插入数据时IDENTITY列我们是没有办法控制的,用这个就可以控制了,只有在使用MSSQL的时候才会用得到

我们编写我们的测试类

package com.fjnu.service;

import java.sql.SQLException;
import static org.junit.Assert.*; import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
import org.xml.sax.InputSource; import com.fjnu.model.User;
import com.weiyuan.dao.IUserDao;
import com.weiyuan.dao.UserDao;
import com.weiyuan.test.DBUtils; public class TestDBUtils {
@Test
public void testLoad(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(
new InputSource(TestDBUtils.class.getClassLoader().getResourceAsStream("t_user.xml"))));
//清空数据库中的数据并插入xml中的数据
DatabaseOperation.CLEAN_INSERT.execute(con,dataSet); IUserDao userDao = new UserDao();
User u = userDao.load("admin");
assertEquals(u.getUsername(), "admin55");
assertEquals(u.getPassword(), "123"); } catch (DatabaseUnitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

这样就可以了

上面这种方式存在问题,它首先是清空数据库中的所有数据,再将xml中的文件插入到数据库中

在实际的操作中:我们应该先备份数据库中的所有数据,然后再操作xml中的数据,然后操作完成之后还原备份的数据

package com.fjnu.service;

import java.io.FileWriter;
import java.sql.SQLException; import static org.junit.Assert.*; import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
import org.xml.sax.InputSource; import com.fjnu.model.User;
import com.weiyuan.dao.IUserDao;
import com.weiyuan.dao.UserDao;
import com.weiyuan.test.DBUtils; public class TestDBUtils {
@Test
public void testLoad(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(
new InputSource(TestDBUtils.class.getClassLoader().getResourceAsStream("t_user.xml"))));
//清空数据库中的数据并插入xml中的数据
DatabaseOperation.CLEAN_INSERT.execute(con,dataSet); IUserDao userDao = new UserDao();
User u = userDao.load("admin");
assertEquals(u.getUsername(), "admin");
assertEquals(u.getPassword(), "123"); } catch (DatabaseUnitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} @Test
public void testBackup(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet createDataSet = con.createDataSet();
FlatXmlDataSet.write(createDataSet, new FileWriter("d:/test.xml"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

IDataSet createDataSet = con.createDataSet();是备份数据库中所有的表

如果我们只备份某张表

可以使用queryDataSet来设置表

package com.fjnu.service;

import java.io.FileWriter;
import java.sql.SQLException; import static org.junit.Assert.*; import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
import org.xml.sax.InputSource; import com.fjnu.model.User;
import com.weiyuan.dao.IUserDao;
import com.weiyuan.dao.UserDao;
import com.weiyuan.test.DBUtils; public class TestDBUtils {
@Test
public void testLoad(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(
new InputSource(TestDBUtils.class.getClassLoader().getResourceAsStream("t_user.xml"))));
//清空数据库中的数据并插入xml中的数据
DatabaseOperation.CLEAN_INSERT.execute(con,dataSet); IUserDao userDao = new UserDao();
User u = userDao.load("admin");
assertEquals(u.getUsername(), "admin");
assertEquals(u.getPassword(), "123"); } catch (DatabaseUnitException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} //备份数据库文件
@Test
public void testBackup(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet createDataSet = con.createDataSet();
FlatXmlDataSet.write(createDataSet, new FileWriter("d:/test.xml"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } //还原数据库文件
@Test
public void testResume(){
try {
IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());
IDataSet dataSet = new FlatXmlDataSet(new FlatXmlProducer(
new InputSource("d:/test.xml")));
//清空数据库中的数据并插入xml中的数据
DatabaseOperation.CLEAN_INSERT.execute(con,dataSet);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } }

05.DBUnit的使用的更多相关文章

  1. Java学习笔记(05)

    目录: static的用法 主函数的定义 增强for的循环 单例设计模式 封装 一.Static的用法 1.对象的内存分析 对象的引用变量是存在于栈区,而在堆区开辟了一块内存空间,调用对象给成员变量赋 ...

  2. iOS系列 基础篇 05 视图鼻祖 - UIView

    iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...

  3. 【web开发 | 移动APP开发】 Web 移动开发指南(2017.01.05更新)

    版本记录 - 版本1.0 创建文章(2016.12.30) - 版本1.1 更正了hybird相关知识:增加了参考文章(2017.01.05): + Web APP更正为响应式移动站点与页面,简称响应 ...

  4. javaSE基础05

    javaSE基础05:面向对象 一.数组 数组的内存管理 : 一块连续的空间来存储元素. Int [ ] arr = new int[ ]; 创建一个int类型的数组,arr只是一个变量,只是数组的一 ...

  5. 异步编程系列第05章 Await究竟做了什么?

    p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...

  6. javascript基础05

    javascript基础05 1.变量的作用域 变量既可以是全局,也可以是局部的. 全局变量:可以在脚本中的任何位置被引用,一旦你在某个脚本里声明了全局变量,你就可以 在这个脚本的任何位置(包括函数内 ...

  7. Linux 第05天

    Linux 第05天 1.连接到Internet 1.1 配置网络信息 dmesg命令————查看网卡信息 dmesg | grep -i net ifconfig命令————查看IP.网关等相关信息 ...

  8. org.dbunit.database.ambiguoustablenameexception

    对于一个数据库下面多个shema的情况,如果使用DBUNIT配置会出现,上面的错误,不清楚的表名,解决如下 增加红色的shema指定 参考:http://stackoverflow.com/quest ...

  9. 转:使用DBUnit测试时违反外键约束的解决办法

    DBUnit是一个基于junit扩展的数据库测试框架.它提供了大量的类对与数据库相关的操作进行了抽象和封装.它会把数据库表里的数据和一个xml文件关联起来,也就是说它可以让数据在XML文件和数据库之间 ...

随机推荐

  1. ArrayList及List的常用方法

    ArrayList package com.aff.coll; import java.util.ArrayList; import java.util.List; import org.junit. ...

  2. DataFrame的apply用法

    DataFrame的apply方法: def cal_value_percent(row,total_value): row['new_column']=row[estimated_value_col ...

  3. 学习Pytorch遇到的一些问题(一)

    基本介绍 这周开始学习深度学习的部分知识,参考的书是<动手学深度学习>(PyTorch版),在操作过程中遇到一些小问题,记录一下问题和解决办法. PyTorch下载过慢 安装步骤 PyTo ...

  4. 关于thisState的那些事

    1.state的定义 状态(state) 和 属性(props) 类似,都是一个组件所需要的一些数据集合,但是它是私有的,并且由组件本身完全控制,可以认为它是组件的“私有属性(或者是局部属性)”. 2 ...

  5. Chisel3 - util - OneHot

    https://mp.weixin.qq.com/s/Jsy8P3m9W2EYKwneGVekiw   独热码相关的电路生成器.   参考链接: https://github.com/freechip ...

  6. java实现第N个素数

    素数就是不能再进行等分的整数.比如:7,11.而9不是素数,因为它可以平分为3等份.一般认为最小的素数是2,接着是3,5,... 请问,第100002(十万零二)个素数是多少? 请注意:2 是第一素数 ...

  7. Java实现提取拼音首字母

    在很多软件中,输入拼音的首写字母就可以快速定位到某个词条.比如,在铁路售票软件中,输入: "bj"就可以定位到"北京".怎样在自己的软件中实现这个功能呢?问题的 ...

  8. 震惊!当Python遇到Excel后,将开启你的认知虫洞

    本文主要内容:   1. Excel,你为什么如此强大 2. 软件开发也需要团队作战 3. Excel的集成方案演化 4. macOS特有的集成方案:applescript 5. Python与Exc ...

  9. Fiddler工具学习使用总结

    1.初识fiddler: 作用:截获http/HTTPS请求,查看截获的请求内容,伪造客户端请求和服务器响应,测试网站性能,解密https的web会话,提供插件. 工作环境:支持素有操作系统和所有浏览 ...

  10. 制作seata docker镜像

    seata是阿里巴巴的一款开源的分布式事务框架,官方已经支持docker了,但是因为业务的需要,需要自己定制. 制作docker镜像 官方的Dockerfile.下载seata-server-1.1. ...