資料表建立與處理


一旦你取得一個IDataSet,就可以使用getTable()指定表格名稱來取得對應的ITable物件,你可以從ITable物件上取得各欄位資料,就如 使用 DbUnit 中的片段:
    ...
        // 取得表格資料
        ITable table = dataSet.getTable("T_BOOKMARK");
        List<Bookmark> expected = new ArrayList<Bookmark>();
        // 表格中的列(row)數
        int rows = table.getRowCount();
        for(int i = 0; i < rows; i++) {
            // 取得每列的各個欄位
            String url = (String) table.getValue(i, "url");
            String title = (String) table.getValue(i, "title");
            String category = (String) table.getValue(i, "category");
            expected.add(new Bookmark(url, title, category));
        }
    ...

如果想得知IDataSet中所有表格名稱,則可以呼叫getTableNames()傳回字串陣列,藉以再搭配getTable()來取得ITable物件。

如果你已經有一個IDatabaseConnection物件,可以直接呼叫createTable(),從指定的資料表中建立ITable物件,無需再透過IDataSet的getTable()方法。例如:
ITable table = dbConn.createTable("T_BOOKMARK");

上例其實相當於:
ITable table = dbConn.createQueryTable("T_BOOKMARK", "SELECT * FROM T_BOOKMARK");

如果你已經有一個PreparedStatement,也可以透過createTable()的另一個版本來建立ITable:
ITable table = dbConn.createTable("T_BOOKMARK", pstmt);

DbUnit的Assertion類別中,assertEquals()可以針對ITable進行斷言,如果想忽略某個欄位,也可以使用assertEqualsIgnoreCols()方法直接傳入IDataSet。例如 的片段:
    ...
    @Test
    public void testAdd() throws Exception {
        // 用待測的DAO安插資料
        Bookmark bookmark = new Bookmark("http://m", "n", "o");
        dao.add(bookmark);

        // 用 DbUnit 取得資料
        IDataSet dataSet = dbConn.createDataSet();
        // 讀取預期資料集合
        IDataSet expected = getXMLDataSet("expected.xml");
        // 斷言資料集合相等性,但忽略id欄位
        assertEqualsIgnoreCols(expected, dataSet,
                "T_BOOKMARK", new String[] {"id"});
    }

    ...

或者你也可以使用IColumnFilter的實作物件來直接過濾ITable物件。例如上例可以改寫為:
    ...
    private ITable getIdIgnoredTable(IDataSet dataSet) throws Exception {
        return DefaultColumnFilter.includedColumnsTable(
                dataSet.getTable("t_bookmark"),
                new String[] {"url", "title", "category"});
    }
   
    @Test
    public void testAdd() throws Exception {
        // 用待測的DAO安插資料
        Bookmark bookmark = new Bookmark("http://m", "n", "o");
        dao.add(bookmark);

        ITable result = getIdIgnoredTable(dbConn.createDataSet());       
        ITable expected = getIdIgnoredTable(getXMLDataSet("expected.xml"));
        Assertion.assertEquals(expected, result);
    }
    ...

如果你想要ITable的結果是排序過後的結果,在呼叫IDatabaseConnectioncreateQueryTable()時,可以指定"ORDER BY"語句,或者你可以使用SortedTable類別來對ITable進行裝飾。例如:
String[] orderBy = {"column1", "column2"};
Assertion.assertEquals(
      new SortedTable(expected, orderBy), new SortedTable(actual, orderBy));

SortedTable預設會使用欄位的toString()字串結果來排序,如果你想要使用Comparable介面定義的方式來排序,可以設定SortedTable的setUseComparable()方法。例如:
String[] orderBy = {"COLUMN1"};
SortedTable sortedTable1 = new SortedTable(table1, orderBy);
sortedTable1.setUseComparable(true);
SortedTable sortedTable2 = new SortedTable(table2, orderBy);
sortedTable2.setUseComparable(true);
Assertion.assertEquals(sortedTable1, sortedTable2);

對於IDataSet,也有個SortedDataSet裝飾類別,可以傳回排序後的SortedTable。

無論是IDataSet或ITable,Assertion的assertEquals()都有一個接受第三個參數為FailureHandler的版本,一旦指定了這個版本,斷言失敗時並不會引發錯誤,而會由FailureHandler加以收集不一致的情況,以便你檢視差異結果。例如:
DiffCollectingFailureHandler diffHandler = new DiffCollectingFailureHandler();
Assertion.assertEquals(expected, dataSet, diffHandler);
for(Object o : diffHandler.getDiffList()) {
    Difference diff  = (Difference) o;
    Object actualValue = diff.getActualValue();
    ...
}