`

写了半天的DAOTest基类。

    博客分类:
  • Java
阅读更多
package test.javayuan.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.Before;

import test.javayuan.exception.TestRuntimeException;

/**
 * @(#)DAOTest.java 2008-12-4 下午12:46:42
 * 
 * @author Qiu Maoyuan
 * DAO Test
 */
public abstract class DAOTest extends BaseTest{
	
	private File backupFile;
	private String backupFileName;
	private String preparedFileName;
	private String[] backupTableNames;
	
	private String jdbcDriverName = "com.mysql.jdbc.Driver";
	private String url = "jdbc:mysql://127.0.0.1:3306/yuan";
	private String username = "root";
	private String password = "";

	protected final IDatabaseConnection databaseConnection = getDatabaseConnection(url, username, password);
	
	protected void setBackupFileName(String backupFileName) {
		this.backupFileName = backupFileName;
	}

	protected void setPreparedFileName(String preparedFileName) {
		this.preparedFileName = preparedFileName;
	}

	protected void setBackupTableNames(String[] backupTableNames) {
		this.backupTableNames = backupTableNames;
	}
	
	/**
	 * SetUp
	 */
	@Before
	public void setUp(){
		onSetUp();
		backupData();
		prepareData();
	}
	
	/**
	 * TearDown
	 */
	@After
	public void tearDown(){
		onTearDown();
		restoreData();
		deleteBackupFile();
		cleanResource();
	}
	
	/**
	 * OnSetUp
	 */
	protected abstract void onSetUp();
	
	/**
	 * OnTearDown
	 */
	protected abstract void onTearDown();
	
	/**
	 * 获取指定文件名的文件:该文件应该是个DBUnit专用的数据文件,应该被放在TestCase类文件所在目录下。<br/>
	 * 如果数据文件不存在,或者存放位置不对,则抛出FileNotFoundException。
	 * @param fileName 文件名
	 * @return 指定文件名的文件
	 * @throws FileNotFoundException 如果数据文件不存在,或者存放位置不对,则抛出FileNotFoundException。
	 */
	protected File getDataFile(String fileName) throws FileNotFoundException{
		String absoluteFilePath = generateAbsolutePath(fileName);
		File file = new File(absoluteFilePath);
		if(!file.exists())
			throw new FileNotFoundException("文件名:" + absoluteFilePath);
		
		return file;
	}
	
	/**
	 * 获取DBUnit数据库连接
	 * @param url 数据库URL
	 * @param user 数据库用户名
	 * @param password 数据库登录密码
	 * @return DBUnit数据库连接
	 */
	private IDatabaseConnection getDatabaseConnection(String url, String user, String password){
		Connection connection; 
		IDatabaseConnection databaseConnection = null;
		try{
			Class.forName(jdbcDriverName);
			connection = DriverManager.getConnection(url, user, password);
			databaseConnection = new DatabaseConnection(connection);
		}catch(Exception ex){
			throw new TestRuntimeException(ex);
		}
		return databaseConnection;
	}
	
	/**
	 * 备份数据库数据
	 */
	private void backupData(){
		if(backupTableNames == null)
			throw new TestRuntimeException("未指定要备份的数据库表:backupTableNames");
		QueryDataSet backupDataSet = new QueryDataSet(databaseConnection);
		FileOutputStream fos = null;
		
		for(String tableName : backupTableNames)
			backupDataSet.addTable(tableName);
		
		try {
			backupFile = createBackupFile();
			fos =  new FileOutputStream(backupFile);
			FlatXmlDataSet.write(backupDataSet, fos);
		} catch (Exception ex){
			throw new TestRuntimeException(ex);
		} finally{
			if(fos != null)
				try {
					fos.close();
				} catch (IOException ex) {
					throw new TestRuntimeException(ex);
				}
		}
	}
	
	/**
	 * 导入“准备数据”
	 */
	private void prepareData(){
		if(preparedFileName == null)
			throw new TestRuntimeException("未指定“准备数据”的文件名:preparedFileName");
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(getDataFile(preparedFileName));
			IDataSet dataSet = new FlatXmlDataSet(fis);
			DatabaseOperation.CLEAN_INSERT.execute(databaseConnection, dataSet);
		} catch (Exception ex) {
			throw new TestRuntimeException(ex);
		} finally{
			if(fis != null)
				try {
					fis.close();
				} catch (IOException ex) {
					throw new TestRuntimeException(ex);
				}
		}
	}

	/**
	 * 还原备份数据
	 */
	private void restoreData(){
		try {
			IDataSet backupData = new FlatXmlDataSet(backupFile);
			DatabaseOperation.CLEAN_INSERT.execute(databaseConnection, backupData);
		} catch (Exception ex) {
			throw new TestRuntimeException(ex);
		}
	}
	
	/**
	 * 删除备份文件
	 */
	private void deleteBackupFile(){
		boolean deleted = backupFile.delete();
		if(!deleted)
			throw new TestRuntimeException("备份文件“"+ backupFile.getAbsolutePath() + "”未正确删除。");
	}
	
	/**
	 * 清理资源
	 */
	private void cleanResource(){
		try {
			databaseConnection.close();
		} catch (Exception ex) {
			throw new TestRuntimeException(ex);
		}
	}
	
	/**
	 * 生成指定文件名的绝对路径<br/>
	 * 生成格式:当前类文件所在绝对路径 + fileName
	 * @param fileName 文件名
	 * @return 指定文件名的绝对路径
	 */
	private String generateAbsolutePath(String fileName){
		return getSystemPath() + getPackagePath() + "/" + fileName;
	}
	
	/**
	 * 创建备份文件<br/>
	 * 如果指定了备份文件的文件名,则创建一个指定文件名的文件;否则,创建一个临时备份文件。
	 * @return 备份文件
	 */
	private File createBackupFile(){

		if(backupFileName != null)
			return new File(generateAbsolutePath(backupFileName));
		else
			try {
				return File.createTempFile("DATABASE_BACKUP", ".xml");
			} catch (IOException ex) {
				throw new TestRuntimeException(ex);
			}
	}
	
	/**
	 * 获取当前类所在包对应的文件路径
	 * @return 当前类所在包对应的文件路径
	 */
	private String getPackagePath(){		
		return getClass().getPackage().getName().replace('.', '/');
	}
	
	/**
	 * 获取当前系统根目录
	 * @return 当前系统根目录
	 */
	private String getSystemPath(){
		return getClass().getClassLoader().getResource("").getFile();
	}
}


BaseTest就这么点内容,主要是加载SpringContext啦:
package test.javayuan.base;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

/**
 * @(#)BaseTest.java 2008-11-25 下午07:44:42
 * 
 * @author Qiu Maoyuan
 * Base Test
 */
@ContextConfiguration(locations={"classpath:spring-config-4test.xml"})
public abstract class BaseTest extends AbstractJUnit4SpringContextTests{

}

实现了个子类,试了试,运行正常:
package test.javayuan.blog.dao;

import java.io.FileInputStream;
import java.util.Date;

import net.javayuan.blog.dao.BlogDAO;
import net.javayuan.blog.entity.Blog;

import org.dbunit.Assertion;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import test.javayuan.base.DAOTest;

/**
 * @(#)BlogDAOTest.java 2008-11-25 下午01:49:12
 * 
 * @author Qiu Maoyuan
 * Blog DAO Test
 */
public class BlogDAOTest extends DAOTest {
	
	@Autowired
	private BlogDAO blogDAO;
	
	public void setBlogDAO(BlogDAO blogDAO){
		this.blogDAO = blogDAO;
	}

	@Override
	protected void onSetUp() {
		this.setBackupFileName("BLOG_BAK.xml");
		this.setPreparedFileName("BLOG_PRE.xml");
		this.setBackupTableNames(new String[]{"t_blog"});
	}

	@Override
	protected void onTearDown() {
		
	}
	
	/**
	 * 测试保存BLOG
	 */
	@Test
	public void testSaveBlog() throws Exception{
		Blog blog = new Blog("title2", "content2");
		blog.setCreatedTime(new Date());
		blogDAO.save(blog);
		
		IDataSet expectedDataSet = new  FlatXmlDataSet(new FileInputStream(getDataFile("BLOG_EXP.xml")));
		ITable expectedTable = expectedDataSet.getTable("t_blog");
		IDataSet databaseDataSet = databaseConnection.createDataSet();
		ITable filteredTable = DefaultColumnFilter.includedColumnsTable(databaseDataSet.getTable("t_blog"),
				expectedTable.getTableMetaData().getColumns());
		
		Assertion.assertEquals(expectedTable, filteredTable);
	}
}

分享到:
评论

相关推荐

    C#写的游戏基类,多人在线游戏引擎

    本资源“C#写的游戏基类,多人在线游戏引擎”提供了一个基础架构,可以帮助开发者理解如何利用C#进行游戏开发,特别是涉及到多人在线游戏功能的实现。其中涉及的主要知识点包括: 1. **C#编程基础**:C#是Microsoft...

    虚基类的使用实例

    ### 虚基类的使用实例详解 #### 一、虚基类概念解析 在C++中,虚基类主要用于解决多继承中的钻石问题(即多个派生类继承自同一个基类,而这些派生类又被另一个类继承,形成一个钻石形状的继承结构)。当一个类同时...

    C#基类整理

    C#基类是其核心部分,提供了丰富的类库,让开发者能够快速构建功能强大的应用程序。以下是对标题和描述中提及的一些关键知识点的详细解释: 1. **ASP.NET类库**:ASP.NET是微软开发的一个用于构建Web应用程序的框架...

    C#基类整理C#比较全的基类集合

    这个压缩包文件“C#基类整理C#比较全的基类集合”可能包含了一系列C#基础类的代码示例和解释,帮助开发者理解和运用这些类。 首先,我们来看一下C#中的几个关键基类: 1. **System.Object**:所有C#类的终极基类,...

    .Net 基类积累

    《.Net 基类积累:深入理解和应用》 在.NET框架中,基类是所有对象的起点,它们提供了一组通用的功能,为其他类提供了基础。Asp.Net中的基类尤其重要,因为它们构成了Web应用程序的核心结构。本文将深入探讨一些...

    C#定义基类并重写基类方法计算图形面积和周长的windows界面程序

    1.定义基类Shape,这有求面积的虚方法Mianji();求周长的虚方法Zhouchang()。 2.定义Shape类的派生类三角形Tangle,使用base关键字调用基类构造函数,重写Shape类继承的虚方法:求面积虚方法Mianji(),求周长虚...

    多继承和虚基类PPT

    "多继承和虚基类PPT" 本资源总结了C++中的多继承和虚基类的概念和应用。多继承是指一个派生类可以继承多个基类的成员,包括数据成员和函数成员。虚基类是解决多继承中出现的命名冲突和继承路径复杂性的机制。 多...

    c# xml操作基类

    c# xml 操作 基类

    C#基类/工具类

    在C#编程中,基类和工具类是两个重要的概念,它们在软件开发过程中起着不可或缺的作用。基类,也称为父类或超类,是用来创建其他类的基础,它定义了共享属性和行为,子类可以继承这些特性,从而实现代码的重用和扩展...

    基类,派生类

    在面向对象编程(Object-Oriented Programming, OOP)中,基类与派生类是两个核心概念。基类(Base Class)也被称为父类或超类,它定义了一组通用的方法和属性,为其他类提供了共享行为的基础。派生类(Derived ...

    虚基类的应用

    虚基类的简单应用 这是平时的一个简单的代码 是自己写着玩的东西

    基于连接池数据库操作基类

    首先,"基于连接池数据库操作基类"是指设计一个基类,该基类使用数据库连接池技术来管理数据库连接。数据库连接池是一种管理数据库连接的机制,它可以重复使用已打开的连接,而不是每次需要时都创建新的连接,这样...

    很好的控件基类

    "很好的控件基类"指的是一个设计良好、功能强大的控件基础类,它为其他特定类型的控件提供了一种可扩展的框架。这个基础类通常包含了一些通用的方法和属性,使得开发人员能够更方便地创建自定义控件,而无需从头开始...

    数据类型的基类

    数据类型的基类

    C++基类指针和派生类指针之间的转换方法讲解

    函数隐藏是指派生类中函数与基类中的函数同名,但是这个函数在基类中并没有被定义为虚函数,这种情况就是函数的隐藏。 所谓隐藏是指使用常规的调用方法,派生类对象访问这个函数时,会优先访问派生类中的这个函数,...

    C#帮助类、各种基类等

    在C#编程中,帮助类(Helper Class)和基类(Base Class)是两种非常重要的设计模式,它们有助于代码的组织、复用和扩展。帮助类通常包含一系列静态方法,提供通用的功能,而基类则作为派生类的起点,为子类提供共享...

    Linux C/C++线程基类源代码

    本文将详细解析标题为“Linux C/C++线程基类源代码”的项目,该基类封装了创建和管理线程的关键操作,方便开发者直接继承和使用。 首先,我们来看`Thread.h`头文件。这个文件通常会定义一个名为`Thread`的基类,它...

    虚基类c++程序

    使用vc6.0编写的关于虚基类的程序的cpp文件,文件来自某大学的大一c++课堂练习

    文件操作基类

    本主题将深入探讨“文件操作基类”的开发,包括文件的读写、排序和删除功能。以下是对这些核心知识点的详细阐述。 首先,我们要创建一个文件操作基类,这个基类可以作为所有与文件交互的类的模板。基类通常包含一些...

Global site tag (gtag.js) - Google Analytics