05.DBUnit的使用
相信做过单元测试的人都会对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的使用的更多相关文章
- Java学习笔记(05)
目录: static的用法 主函数的定义 增强for的循环 单例设计模式 封装 一.Static的用法 1.对象的内存分析 对象的引用变量是存在于栈区,而在堆区开辟了一块内存空间,调用对象给成员变量赋 ...
- iOS系列 基础篇 05 视图鼻祖 - UIView
iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...
- 【web开发 | 移动APP开发】 Web 移动开发指南(2017.01.05更新)
版本记录 - 版本1.0 创建文章(2016.12.30) - 版本1.1 更正了hybird相关知识:增加了参考文章(2017.01.05): + Web APP更正为响应式移动站点与页面,简称响应 ...
- javaSE基础05
javaSE基础05:面向对象 一.数组 数组的内存管理 : 一块连续的空间来存储元素. Int [ ] arr = new int[ ]; 创建一个int类型的数组,arr只是一个变量,只是数组的一 ...
- 异步编程系列第05章 Await究竟做了什么?
p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...
- javascript基础05
javascript基础05 1.变量的作用域 变量既可以是全局,也可以是局部的. 全局变量:可以在脚本中的任何位置被引用,一旦你在某个脚本里声明了全局变量,你就可以 在这个脚本的任何位置(包括函数内 ...
- Linux 第05天
Linux 第05天 1.连接到Internet 1.1 配置网络信息 dmesg命令————查看网卡信息 dmesg | grep -i net ifconfig命令————查看IP.网关等相关信息 ...
- org.dbunit.database.ambiguoustablenameexception
对于一个数据库下面多个shema的情况,如果使用DBUNIT配置会出现,上面的错误,不清楚的表名,解决如下 增加红色的shema指定 参考:http://stackoverflow.com/quest ...
- 转:使用DBUnit测试时违反外键约束的解决办法
DBUnit是一个基于junit扩展的数据库测试框架.它提供了大量的类对与数据库相关的操作进行了抽象和封装.它会把数据库表里的数据和一个xml文件关联起来,也就是说它可以让数据在XML文件和数据库之间 ...
随机推荐
- pandas 小技巧
1.找出某个字段包含某字符串的行: my_df[my_df['col_B'].str.contains('大连') > 0]或者 my_df[my_df['col_B'].apply(lambd ...
- 【JVM】堆体系结构及其内存调优
堆体系结构 一个JVM实例只存在一个堆内存,堆内存的大小是可调节的.类加载器读取类文件后,需要把类.方法.常量.变量放在堆内存中,保存所有引用类型的真实信息,以方便执行器指向,堆内存分为三个部分:年轻 ...
- 05 . Python入门值循环语句
一.Python循环语句 程序一般情况下是按照顺序执行的 编程语言提供了各种控制结构,允许更复杂的执行路径 Python中的循环语句有for和while但没有do while 循环语句允许我们执行一个 ...
- 循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理
在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询.列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表 ...
- MethodHandle(方法句柄)系列之三:invoke和invokeExact的区别
先把代码贴上来,用的是一样的代码 /** * * @author LiuYeFeng<897908343@qq.com> * @date 2015年4月8日 下午10:41:13 * @C ...
- Java实现 LeetCode 383 赎金信
383. 赎金信 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成.如果可以构成,返回 t ...
- java实现 洛谷 P1427 小鱼的数字游戏
题目描述 小鱼最近被要求参加一个数字游戏,要求它把看到的一串数字(长度不一定,以0结束,最多不超过100个,数字不超过2^32-1),记住了然后反着念出来(表示结束的数字0就不要念出来了).这对小鱼的 ...
- java实现第六届蓝桥杯三羊献瑞
三羊献瑞 题目描述 观察下面的加法算式: 祥 瑞 生 辉 三 羊 献 瑞 三 羊 生 瑞 气 (如果有对齐问题,可以参看[图1.jpg]) 其中,相同的汉字代表相同的数字,不同的汉字代表不同的数字. ...
- SpringSecurity(2)---记住我功能实现
SpringSecurity(2)---记住我功能实现 上一篇博客实现了认证+授权的基本功能,这里在这个基础上,添加一个 记住我的功能. 上一篇博客地址:SpringSecurity(1)---认证+ ...
- ES6优雅的异步操作Promise()
一.Promise()的基本使用 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...