DbUnitでは初期値や期待値をXMLやExcelに記述することができる。
ただ、nullを表現したいときは困ってしまう。
たとえばXMLで次のように記述したとする。
<?xml version='1.0' encoding='UTF-8'?> <dataset> <HUMAN NAME="jyukutyo" NULLCOLUMN="" /> </dataset>
この場合、NULLCOLUMNはnullではなく空文字となる。
本当にそうなるかサンプルプログラムで読み込んで出力してみる。
public static void main(String[] args) throws Exception { FlatXmlDataSet dataSet = new FlatXmlDataSet(new File("data.xml")); output(dataSet); } protected static void output(IDataSet dataSet) throws DataSetException { for (String name : dataSet.getTableNames()) { ITable table = dataSet.getTable(name); System.out.println("Table name:" + table.getTableMetaData().getTableName()); Column[] columns = table.getTableMetaData().getColumns(); for (int i = 0; i < table.getRowCount(); i++) { System.out.print("Row:" + i + "["); for (int j = 0; j < columns.length; j++) { Column column = columns[j]; System.out.print(column.getColumnName() + "={" + table.getValue(i, column.getColumnName()) + "},"); } System.out.println("]"); } } }
さっきのXMLをdata.xmlとしてる。
実行するとこう出力される。
Table name:HUMAN Row:0[NAME={jyukutyo},NULLCOLUMN={},]
もし、nullであればこう出力されなければならない*1。
Table name:HUMAN Row:0[NAME={jyukutyo},NULLCOLUMN={null},]
Excelを使っていても同様の事態になる。
ではDbUnitはnullを初期値や期待値として表現できないのか、
というとそうではなくて、ReplacementDataSetクラスを利用する。
これはDataSetをラップするオブジェクトで、後から値を置き換えることができる。
なので、XMLをこう変更する。
<?xml version='1.0' encoding='UTF-8'?> <dataset> <HUMAN NAME="jyukutyo" NULLCOLUMN="[null]" /> </dataset>
[null]と書いたがこれは任意でよく、後から置き換えるためのマーカーにすぎない。
プログラムで[null]をnullに置き換えるよう変更する。
public static void main(String[] args) throws Exception { FlatXmlDataSet dataSet = new FlatXmlDataSet(new File("data.xml")); ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet); replacementDataSet.addReplacementObject("[null]", null); output(replacementDataSet); }
実行するとNULLCOLUMNはnullになる。
Table name:HUMAN Row:0[NAME={jyukutyo},NULLCOLUMN={null},]
これを応用すれば、たとえばTimestampで現在時刻を設定するということもできる。
<?xml version='1.0' encoding='UTF-8'?> <dataset> <HUMAN NAME="jyukutyo" NULLCOLUMN="[null]" TIMESTAMP="[now]" /> </dataset>
replacementDataSet.addReplacementObject("[now]", new Timestamp(System.currentTimeMillis()));
Table name:HUMAN Row:0[NAME={jyukutyo},NULLCOLUMN={null},TIMESTAMP={2008-08-21 13:52:22.044},]
ちなみに、置き換える値が複数の行にあっても、すべて置換される。
*1:+演算子はStringBuffer#append()だから