06.DBUnit实际运用

在上面的代码中

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.Before;
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.dao.UserDaoByHashMapImpl;
import com.weiyuan.test.DBUtils;

public class TestDBUtils {
    
    @Before
    public void setUp(){
        // 初始化
        System.out.println("setup is called");
        
    }
    @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();
        }
        
    }

}

每次执行一个测试方法都会调用 IDatabaseConnection con = new DatabaseConnection(DBUtils.getConnection());创建一个连接对象,不太好,我们只希望在一个测试业务类中创建一个连接对象,如何实现了

可以使用

JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation:
@Before:初始化方法 对于每一个测试方法都要执行一次(注意与BeforeClass区别,后者是对于所有方法执行一次)
@After:释放资源 对于每一个测试方法都要执行一次(注意与AfterClass区别,后者是对于所有方法执行一次)
@Test:测试方法,在这里可以测试期望异常和超时时间
@Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常
@Ignore:忽略的测试方法
@BeforeClass:针对所有测试,只执行一次,且必须为static void
@AfterClass:针对所有测试,只执行一次,且必须为static void

我们使用@BeforeClass保证创建业务类都只执行一次

我们首先在原来的基础上封装一个抽象类

 
 
package com.weiyuan.dao;

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

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
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.FlatXmlDataSetBuilder;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.util.Base64.InputStream;
import org.junit.BeforeClass;
import org.xml.sax.InputSource;

import static org.junit.Assert.*;

import com.weiyuan.test.DBUtils;

/**
 * DBUnit Dao数据库 测试 的抽象类,
 * Dao层方法的测试只需继承此类,
 * 并调用相应的方法即可完成隔离真实数据层的数据测试
 * @author 
 * 2015.08.11
 *
 */
public abstract class AbstractDbUnitTestCase {
    
    //数据库链接
    public static IDatabaseConnection dbunitCon ;
    //备份真实数据的文件
    private File tempFile ; 
    
    @BeforeClass
    //在类执行之前执行,初始化数据库链接
    public static void init() throws Exception{
         
        dbunitCon = new DatabaseConnection(DBUtils.getConnection());
    }
    
    /**
     * 构建初始 测试 数据集
     * @param tname 要构建的数据集的数据文件名 tname.xml
     * @return 
     * @throws DataSetException
     */
    protected IDataSet createDataSet(String tname) {
        //获取预置数据集
        //com.weiyuan.dao对应存在xml文件的路径,这里也可以是文件夹dbutils_xml这个文件夹必须在src目录下
        java.io.InputStream is = AbstractDbUnitTestCase.class.getClassLoader().getResourceAsStream("dbutils_xml/"+tname+".xml");
        
        assertNotNull("dbunit的基本文件 "+tname+".xml 不存在",is);
        //构建数据集
        IDataSet dataSet = null;
        try {
            dataSet = new FlatXmlDataSetBuilder().build(is);
        } catch (DataSetException e) {
            e.printStackTrace();
        }  
        
        return dataSet ;
    }
    
    
    
    //===========备份真实数据的公共方法==========================================================//
    
    /**
     * 备份数据表
     * @param tname
     * @throws DataSetException
     * @throws IOException
     */
    protected void backUpOneTable(String tname) {
        backUpCustomTable(new String[]{tname});
    }
    /**
     * 同时备份多张表
     * @param tname
     * @throws DataSetException
     * @throws IOException
     */
    protected void backUpCustomTable(String[] tname) {
        try {
            QueryDataSet queryDataSet = new QueryDataSet(dbunitCon);
            for(String str : tname){
                queryDataSet.addTable(str);
            }
            writeBackUpFile(queryDataSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    /**
     * 备份全部的真实数据表
     * @author sangwenhao
     * 2015.08.10
     */
    protected void backUpAllTable(){
        try {
            IDataSet dataSet = dbunitCon.createDataSet();
            //保存到物理文件
            writeBackUpFile(dataSet);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    /**
     * 保存临时文件(数据库中真实数据)操作
     * @param dataSet
     * @author sangwenhao
     * 2015.08.11
     */
    protected void writeBackUpFile(IDataSet dataSet) {
        
        try {
            tempFile = File.createTempFile("back", "xml");
            FlatXmlDataSet.write(dataSet, new FileWriter(tempFile) );
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DataSetException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 恢复数据表中的原始数据
     * @author sangwenhao
     * 2015.08.10
     */
    protected void resumeTable() {
        try {
            //读取 备份的真实数据集
            IDataSet ds = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(new FileInputStream(tempFile))));
            //执行 插入数据 操作
            DatabaseOperation.CLEAN_INSERT.execute(dbunitCon, ds);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    /**
     * 销毁链接
     * @author sangwenhao
     * 2015.08.10
     */
    protected void destory() {
        try {
            if(dbunitCon != null) dbunitCon.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}
 
  
 
接下来编写我们的测试类
package com.fjnu.service;

import static org.junit.Assert.*;

import java.sql.SQLException;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.fjnu.model.User;
import com.weiyuan.dao.AbstractDbUnitTestCase;
import com.weiyuan.dao.UserDao;
import com.weiyuan.dao.UserDaoByHashMapImpl;
import com.weiyuan.test.DBUtils;


/*
 * 因为TestDBUtilsUserService继承AbstractDbUnitTestCase
 * TestDBUtilsUserService在创建都会调用@BeforeClass
    //在类执行之前执行,初始化数据库链接
    public static void init() throws Exception{
         
        dbunitCon = new DatabaseConnection(DBUtils.getConnection());
    }
    init方法之后调用一次
 * 
 * */
public class TestDBUtilsUserService extends AbstractDbUnitTestCase {
    private IUserService us;
    private User baseUser;
      IDataSet dataSet ;
    
    //该方法每次在调用任何测试方法都会被调用
    @Before
    public void setUp(){
        // 初始化
        System.out.println("setup is called");
        us = new UserService(new UserDao());
        //调用任何测试方法之前都备份t_user表的原始任何数据
        backUpOneTable("t_user");
        baseUser = new User("admin", "123", "管理员");
        //调用任何测试方法之前都通过xml文件创建测试数据
        dataSet = createDataSet("t_user");
    }
    
    private void assertUserEquals(User u, User tu){
        assertEquals("add方法有错误!", u.getUsername(), tu.getUsername());
        assertEquals("add方法有错误!", u.getNickname(), tu.getNickname());
        assertEquals("add方法有错误!", u.getPassword(), tu.getPassword());
    }
    @Test
   public void testLoad(){
        
        try {
            DatabaseOperation.CLEAN_INSERT.execute(dbunitCon, dataSet);
            User u = us.load("admin");
            assertUserEquals(u,baseUser);
        } catch (DatabaseUnitException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    @After
    public void tearDown(){
        resumeTable();
    }
    
    
    

}
 
 

整个工程的项目路径如下所示

 项目的下载地址是:
https://pan.baidu.com/s/15zkog89J75tbgiOPF3cmdA
密码 ycva

猜你喜欢

转载自www.cnblogs.com/kebibuluan/p/8908334.html