在上面的代码中
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