JUnitを使ったテストで、入れ子になったオブジェクトをassertEquals()で精査するのは、死ぬほど面倒なので、フレームワーク精査用のライブラリを用意。
期待するオブジェクト
オブジェクトのダンプはこんな感じ。
ArrayList(11) {
[0]=>
String(5) "value"
[1]=>
String(1) "値"
[2]=>
ArrayList(2) {
[0]=>
String(13) "nested value1"
[1]=>
String(6) "入れ子の値1"
}
[3]=>
ArrayList(2) {
[0]=>
String(13) "nested value2"
[1]=>
String(6) "入れ子の値2"
}
[4]=>
HashMap(2) {
["foo"]=>
String(3) "bar"
["hoge"]=>
String(6) "hogera"
}
[5]=>
HashMap(2) {
["hogera"]=>
String(4) "hoge"
["bar"]=>
String(3) "foo"
}
[6]=>
HashMap(2) {
["egoh"]=>
String(8) "egohegoh"
["oof"]=>
String(3) "rab"
}
[7]=>
int(3) {
[0]=>
Integer "10"
[1]=>
Integer "11"
[2]=>
Integer "12"
}
[8]=>
String(3) {
[0]=>
String(2) "20"
[1]=>
String(2) "21"
[2]=>
String(2) "22"
}
[9]=>
sample.SampleBean {
["value"]=>
String(6) "Beanの値"
["subBean"]=>
sample.SampleBean {
["value"]=>
String(9) "入れ子の値 その1"
["subBean"]=>
sample.SampleBean {
["value"]=>
String(9) "入れ子の値 その2"
["subBean"]=>
null
["id"]=>
Integer "999"
}
["id"]=>
Integer "99"
}
["id"]=>
Integer "9"
}
[10]=>
sample.SampleBean2 {
["age"]=>
String(2) "20"
["name"]=>
String(4) "山田太郎"
}
}
XMLのデータはこんな感じ。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bodybuilder>
<bodybuilder>
<list>
<add value="value"/>
<add value="値"/>
<add>
<!-- 入れ子のList その1-->
<list>
<add value="nested value1"/>
<add value="入れ子の値1"/>
</list>
</add>
<add>
<!-- 入れ子のList その2-->
<list>
<listvals v1="nested value2" v2="入れ子の値2"/>
</list>
</add>
<add>
<!-- Map その1 -->
<map>
<foo value="bar"/>
<hoge value="hogera"/>
</map>
</add>
<add>
<!-- Map その2 -->
<map>
<put name="bar" value="foo"/>
<put name="hogera" value="hoge"/>
</map>
</add>
<add>
<!-- Map その3 -->
<map>
<mapvals oof="rab" egoh="egohegoh"/>
</map>
</add>
<add>
<!-- 配列 その1 -->
<array type="int">
<elem value="10"/>
<elem value="11"/>
<elem value="12"/>
</array>
</add>
<add>
<!-- 配列 その2 -->
<array>
<listvals v1="20" v2="21" v3="22"/>
</array>
</add>
<add>
<!-- Bean その1 -->
<bean type="sample.SampleBean">
<id value="9" type="int"/>
<value value="Beanの値"/>
<subBean>
<!-- 入れ子のBean その1 -->
<bean type="sample.SampleBean">
<prop name="id" value="99" type="int"/>
<prop name="value" value="入れ子の値 その1"/>
<prop name="subBean">
<!-- 入れ子のBean その2 -->
<bean type="sample.SampleBean">
<prop name="id" value="999" type="int"/>
<prop name="value" value="入れ子の値 その2"/>
</bean>
</prop>
</bean>
</subBean>
</bean>
</add>
<add>
<!-- Bean その2 -->
<bean type="sample.SampleBean2">
<mapvals name="山田太郎" age="20"/>
</bean>
</add>
</list>
</bodybuilder>
入力されたオブジェクト
オブジェクトのダンプはこんな感じ。
ArrayList(11) {
[0]=>
String(5) "value"
[1]=>
String(1) "値"
[2]=>
ArrayList(2) {
[0]=>
String(13) "nested value1"
[1]=>
String(6) "入れ子の値1"
}
[3]=>
ArrayList(2) {
[0]=>
String(13) "nested value2"
[1]=>
String(6) "入れ子の値2"
}
[4]=>
HashMap(2) {
["foo"]=>
String(3) "bar"
["hoge"]=>
String(6) "hogera"
}
[5]=>
HashMap(2) {
["hogera"]=>
String(4) "hoge"
["bar"]=>
String(3) "foo"
}
[6]=>
HashMap(2) {
["egoh"]=>
String(8) "egohegoh"
["oof"]=>
String(3) "rab"
}
[7]=>
int(3) {
[0]=>
Integer "10"
[1]=>
Integer "11"
[2]=>
Integer "12"
}
[8]=>
String(3) {
[0]=>
String(2) "20"
[1]=>
String(2) "21"
[2]=>
String(2) "22"
}
[9]=>
sample.SampleBean {
["value"]=>
String(6) "Beanの値"
["subBean"]=>
sample.SampleBean {
["value"]=>
String(9) "入れ子の値 その1"
["subBean"]=>
sample.SampleBean {
["value"]=>
String(9) "入れ子の値 その2"
["subBean"]=>
null
["id"]=>
Integer "0" ←※間違い
}
["id"]=>
Integer "99"
}
["id"]=>
Integer "9"
}
[10]=>
sample.SampleBean2 {
["age"]=>
String(2) "20"
["name"]=>
String(4) "山田太郎"
}
}
XMLのデータはこんな感じ。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bodybuilder>
<bodybuilder>
<list>
<add value="value"/>
<add value="値"/>
<add>
<!-- 入れ子のList その1-->
<list>
<add value="nested value1"/>
<add value="入れ子の値1"/>
</list>
</add>
<add>
<!-- 入れ子のList その2-->
<list>
<listvals v1="nested value2" v2="入れ子の値2"/>
</list>
</add>
<add>
<!-- Map その1 -->
<map>
<foo value="bar"/>
<hoge value="hogera"/>
</map>
</add>
<add>
<!-- Map その2 -->
<map>
<put name="bar" value="foo"/>
<put name="hogera" value="hoge"/>
</map>
</add>
<add>
<!-- Map その3 -->
<map>
<mapvals oof="rab" egoh="egohegoh"/>
</map>
</add>
<add>
<!-- 配列 その1 -->
<array type="int">
<elem value="10"/>
<elem value="11"/>
<elem value="12"/>
</array>
</add>
<add>
<!-- 配列 その2 -->
<array>
<listvals v1="20" v2="21" v3="22"/>
</array>
</add>
<add>
<!-- Bean その1 -->
<bean type="sample.SampleBean">
<id value="9" type="int"/>
<value value="Beanの値"/>
<subBean>
<!-- 入れ子のBean その1 -->
<bean type="sample.SampleBean">
<prop name="id" value="99" type="int"/>
<prop name="value" value="入れ子の値 その1"/>
<prop name="subBean">
<!-- 入れ子のBean その2 -->
<bean type="sample.SampleBean">
<prop name="id" value="000" type="int"/>
<!-- ~~~ 間違い -->
<prop name="value" value="入れ子の値 その2"/>
</bean>
</prop>
</bean>
</subBean>
</bean>
</add>
<add>
<!-- Bean その2 -->
<bean type="sample.SampleBean2">
<mapvals name="山田太郎" age="20"/>
</bean>
</add>
</list>
</bodybuilder>
テストコード
こんな感じ。
package sample;import junit.framework.AssertionFailedError;
import bodybuilder.builder.Bullworker;
import bodybuilder.inspector.Inspector;
import bodybuilder.viewer.Viewer;
public class Sample {
public static void main(String[] args) {
Bullworker sample1 = new Bullworker(
"C:\\eclipse3\\workspace\\bodybuilder\\data\\sample1.xml");
Bullworker sample2 = new Bullworker(
"C:\\eclipse3\\workspace\\bodybuilder\\data\\sample2.xml");
Object expected = sample1.getMuscle();
Object actual = sample2.getMuscle();
//Viewer.dump(expected);
//Viewer.dump(actual);
try {
Inspector.assertEquals(expected, actual);
} catch (AssertionFailedError e) {
e.printStackTrace();
}
}
}
テストの実行結果
こんな感じ。
junit.framework.AssertionFailedError: objects differ expected:<999> but was:<0>
ArrayList(11) {
[9]=>
SampleBean {
["subBean"]=>
SampleBean {
["subBean"]=>
SampleBean {
["id"]=>
Integer at bodybuilder.inspector.Inspector.rethrow(Inspector.java:115)
at bodybuilder.inspector.Inspector.rethrow(Inspector.java:93)
at bodybuilder.inspector.Inspector.assertObjectEquals(Inspector.java:37)
at bodybuilder.inspector.BeanInspector.assertEquals(BeanInspector.java:25)
at bodybuilder.inspector.Inspector.assertObjectEquals(Inspector.java:33)
at bodybuilder.inspector.BeanInspector.assertEquals(BeanInspector.java:25)
at bodybuilder.inspector.Inspector.assertObjectEquals(Inspector.java:33)
at bodybuilder.inspector.BeanInspector.assertEquals(BeanInspector.java:25)
at bodybuilder.inspector.Inspector.assertObjectEquals(Inspector.java:33)
at bodybuilder.inspector.ListInspector.assertEquals(ListInspector.java:17)
at bodybuilder.inspector.Inspector.assertObjectEquals(Inspector.java:33)
at bodybuilder.inspector.Inspector.assertEquals(Inspector.java:12)
at sample.Sample.main(Sample.java:21)
TODO
- サーブレットAPIへの対応。
- MockRunner、StrutsTestCaseへの対応。
オブジェクトを再帰的に比較するAssertクラスの作成。
- XMLの一ファイルを一テストケースとするテストユーティリティの作成。
- ロギングの追加。
- コンストラクタへの対応。
- 特殊値(null、日付型、改行を含む文字列)への対応。
Bullworkerクラスの進退。
スタックトレースをも少し見やすく。