DbUnit 可以使用XML建立資料集,DbUnit提供了許多建立資料集的方式,其中最常用的是XmLDataSet與FlatXmlDataSet。首先看到XmlDataSet的建 立所需的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<table name="t_bookmark">
<column>id</column>
<column>url</column>
<column>title</column>
<column>category</column>
<row>
<value>1</value>
<value>http://a</value>
<value>b</value>
<value>c</value>
</row>
<row>
<value>2</value>
<value>http://x</value>
<value>y</value>
<value>z</value>
</row>
</table>
</dataset>
其中dataset.dtd如下:
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT dataset (table+) | ANY>
<!ELEMENT table (column*, row*)>
<!ATTLIST table
name CDATA #REQUIRED
>
<!ELEMENT column (#PCDATA)>
<!ELEMENT row (value | null | none)*>
<!ELEMENT value (#PCDATA)>
<!ELEMENT null EMPTY>
如果想要讀取這樣的XML文件,可以使用XmLDataSet。例如:
IDataSet dataSet = new XmlDataSet(new
FileInputStream("dataset.xml"));
然而這樣建立的XML文件太冗長而不易撰寫,你可以採用FlatXmlDataset的格式,撰 寫起來比較簡潔:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<t_bookmark id="1" url="http://a" title="b" category="c"/>
<t_bookmark id="2" url="http://x" title="y" category="z"/>
</dataset>
如果想要讀取這樣的XML文件,可以使用FlatXmLDataSetBuilder。例如:
IDataSet
dataSet = new FlatXmlDataSetBuilder()
.build(new FileInputStream("dataset.xml"));
.build(new FileInputStream("dataset.xml"));
IDataSet代 表著資料集合,資料集合的來源可能是XML文件或資料庫。你可以從XML文件建立IDataSet實作物件, 再將之安插至資料庫中。例如 使用 DbUnit 中看到的片段:
...
// 讀取指定的資料集合
private static IDataSet getXMLDataSet(String file) throws Exception {
return new FlatXmlDataSetBuilder()
.build(new FileInputStream(file));
}
@Before
public void setUp() throws Exception {
// 測試前讀入初始資料集合、清除表格並將初始資料集合新增至資料庫中的表格
DatabaseOperation.CLEAN_INSERT.execute(dbConn, getXMLDataSet("dataset.xml"));
dao = new BookmarkDAOImpl(dataSource);
}
...
如果你有一個IDatabaseConnection 實作物件,可以呼叫createDataSet(),這會取得資料庫的資料,並建立IDataSet實作物件,如果你想要將之寫至XML文件,則可以利用XmlDataSetWriter或FlatXmlWriter的write()方法。例如:
// dbConn是IDatabaseConnection實作物件
IDataSet dataSet = dbConn.createDataSet();
new FlatXmlWriter(new FileOutputStream("some.xml")).write(dataSet);
IDataSet dataSet = dbConn.createDataSet();
new FlatXmlWriter(new FileOutputStream("some.xml")).write(dataSet);
如 果不想將資料庫中的資料全部用來建立IDataSet,則呼叫createDataSet()時可以指定表格:
IDataSet dataSet = dbConn.createDataSet(new
String[] { "t_bookmark" });
也可以使用QueryDataSet。例如:
// dbConn是IDatabaseConnection實作物件
QueryDataSet dataSet = new QueryDataSet(dbConn);
// 將a_table加入資料集
dataSet.addTable("a_table");
// 將SELECT出的資料加入資料集
dataSet.addTable("t_bookmark", "SELECT * FROM t_bookmark WHERE id < 10");
QueryDataSet dataSet = new QueryDataSet(dbConn);
// 將a_table加入資料集
dataSet.addTable("a_table");
// 將SELECT出的資料加入資料集
dataSet.addTable("t_bookmark", "SELECT * FROM t_bookmark WHERE id < 10");
如果有一個現成的 IDataSet,則可以使用FilteredDataSet來過 濾。例如:
FilteredDataSet filteredDataSet = new
FilteredDataSet(
new String[] {"t_bookmark"}, dataSet);
new String[] {"t_bookmark"}, dataSet);
如果在設定XML時,某些值暫時無法確定,例如在 使用 DbUnit 中看到的片段:
...
@Test
public void testAdd() throws Exception {
// 用待測的DAO安插資料
Bookmark bookmark = new Bookmark("http://m", "n", "o");
dao.add(bookmark);
// 用 DbUnit 取得資料
IDataSet dataSet = databaseTester.getConnection().createDataSet();
// 讀取預期資料集合
IDataSet expected = getXMLDataSet("expected.xml");
// 斷言資料集合相等性,但忽略id欄位
assertEqualsIgnoreCols(expected, dataSet,
"T_BOOKMARK", new String[] {"id"});
}
...
由於資料庫中的 id是自動遞增,因此在上面的片段中忽略了id欄位來進行比較。另一個方式是使用ReplacementDataSet, 替代掉資料集中的id值。例如你可以先在expected.xml中如下撰寫:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<t_bookmark id="1" url="http://a" title="b" category="c"/>
<t_bookmark id="2" url="http://x" title="y" category="z"/>
<t_bookmark id="[ID]" url="http://m" title="n" category="o"/>
</dataset>
之後在 testAdd()中取代掉[ID]的值:
...
@Test
public void testAdd() throws Exception {
// 用待測的DAO安插資料
Bookmark bookmark = new Bookmark("http://m", "n", "o");
dao.add(bookmark);
// 用 DbUnit 取得資料
IDataSet dataSet = databaseTester.getConnection().createDataSet();
// 取得表格資料
ITable table = dataSet.getTable("T_BOOKMARK");
// 取得最後一筆資料的id值
Integer lastId = (Integer) table.getValue(table.getRowCount() - 1, "id");
// 讀取預期資料集合
IDataSet expected = getXMLDataSet("expected.xml");
ReplacementDataSet replacementDataSet = new ReplacementDataSet(expected);
// 取代[ID]值
replacementDataSet.addReplacementObject("[ID]", lastId);
expected = replacementDataSet;
// 斷言資料集是否相等
Assertion.assertEquals(expected, dataSet);
}
...
你也可以為FlatXMLDataSet產 生DTD檔案。例如:
new FlatDtdWriter(new
FileWriter("some.dtd")).write(dataSet);
一個產生的DTD檔案範例如下:
<!ELEMENT dataset (
t_bookmark*)>
<!ELEMENT t_bookmark EMPTY>
<!ATTLIST t_bookmark
id CDATA #REQUIRED
url CDATA #REQUIRED
title CDATA #REQUIRED
category CDATA #REQUIRED
>
如果你想要將XML置於Classpath,則可以使用DataFileLoader來 取得。例如:
DataFileLoader loader = new
FlatXmlDataFileLoader();
IDataSet dataSet = loader.load("dataSet.xml"); // dataSet.xml置於Classpath中
IDataSet dataSet = loader.load("dataSet.xml"); // dataSet.xml置於Classpath中