日期:2014-05-16  浏览次数:20407 次

DBUnit使用

前言:本文章需要JUnit单元测试框架的基础知识,若读者还不具备,请阅读笔者的JUnit文章:http://ray-yui.iteye.com/blog/1914106


UnitTest系列文章:
      使用JUnit开发单元测试:http://ray-yui.iteye.com/blog/1914106
      使用EasyMock扩展Junithttp://ray-yui.iteye.com/blog/1916170
      使用Cactus测试Servlethttp://ray-yui.iteye.com/blog/1917515
      使用Spring TestContext测试Spring应用http://ray-yui.iteye.com/blog/1921424

什么是DBUnit?
      DBUnit是一个基于JUnit扩展的数据库测试框架。它能帮助我们更方便快捷的进行数据库测试.

为什么要使用DBUnit?
      在我们使用JUnit单元测试框架编写单元测试的时候,少不免要对数据库进行操作,但请试想一下,当我要编写一个获取用户的单元测试时,数据库是不存在该记录的,那么我要测试获取用户时就需要往数据库添加一条用户记录,但当获取用户的单元测试完成并成功后,此测试并没有清理现场(删除插入数据库的记录),那样当我们再有单元测试需要插入记录时,就会造成ID冲突的情况,少量的单元测试还可以避免此种情况,但当单元测试的数据庞大时,就会出现各种各样的问题,而DBUnit可以帮助我们解决这类型的问题

DBUnit为我们做了什么?
      DBUnit的设计理念是在测试之前,先对数据库进行备份,然后对数据库进行清空再插入我们为其准备的测试数据,最后在测试完毕后重新恢复数据库从而避免了JUnit对数据现场的破坏.

DBUnit使用:
      1.首先为Maven增加DBUnit的依赖,还需要slf4j的依赖

<dependency>
	<groupId>org.dbunit</groupId>
	<artifactId>dbunit</artifactId>
	<version>2.4.9</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.5</version>
	<scope>compile</scope>
</dependency>



      在Maven管理的项目src/test/resource/下创建default-data.xml

<?xml version="1.0" encoding="UTF-8"?>
<dataset>

	<!-- 注意,此处的user代表表名(database table name) -->
	<user id="1" username="123" password="456"/>
	<user id="2" username="123" password="456"/>
	<user id="3" username="123" password="456"/>
	<user id="4" username="123" password="456"/>
	<user id="5" username="123" password="456"/>
</dataset>



      以下代码为提取后的BaseTest

package com.accentrix.ray;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;

import javax.sql.DataSource;

import org.dbunit.database.DatabaseDataSourceConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.DataSetException;
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.AfterClass;
import org.junit.BeforeClass;
import org.xml.sax.InputSource;

public class BaseTest {
	public static IDatabaseConnection connection;
	public static DataSource dataSource;
	private File temp;

	@BeforeClass
	public static void init() throws Exception {

		// 通过DataSource获取DataBaseSourceConnection
		connection = new DatabaseDataSourceConnection(dataSource);
	}

	@AfterClass
	public static void destroy() throws Exception {
		if (connection != null) {
			connection.close();
		}
	}

	protected IDataSet getDataSet(String name) throws DataSetException {
		// 通过类加载器获取default-data.xml文件的内容
		InputStream is = this.getClass().getClassLoader()
				.getResourceAsStream(name + ".xml");

		// IDataSet就类似是一个数据的容器,把default-data.xml内容
		// 转换成了DBUnit可识别的数据返回出去
		return new FlatXmlDataSet(new FlatXmlProducer(new InputSource(is)));
	}

	protected void backupAll() throws Exception {
		// createDataSet代表从数据库中获取到DataSet,此时DataSet为数据库的内容
		IDataSet ds = connection.createDataSet();

		// 创建临时文件
		temp = File.createTempFile("temp", "xml");

		// 将数据库内容的DataSet写入临时文件当中
		F