こんなクラスがあるとする。
public class Foo { private final Bar bar = new Bar(); public String hoge() { return this.bar.baz().hoge(); } }見ての通り、Foo は メソッド hoge()の中で、関連オブジェクト bar から取得した baz に、hoge() 処理を移譲している(日本語にすると、なんのこっちゃだが…)。
Bar と Baz は以下のような感じで後回しにしてある。
public class Bar { public Baz baz() { throw new AssertionError(); } } public class Baz { public String hoge() { throw new AssertionError(); } }
ここで、Foo#hoge() をテストするにはどうするか。つまり以下の/* ??? */ のところに何を入れたらテストできるか。
public class FooTest { @Test public void hoge() { /* ??? */ Assert.assertEquals("hello", new Foo().hoge()); } }
とりあえず2個だけ例を書いてみると(ちょっとずつニュアンスの違うものを何通りも書けるが)、以下のようになる。
@Test public void hoge1() { new Expectations() { @Mocked("baz") Bar bar; @Mocked("hoge") Baz baz; { bar.baz(); result = baz; baz.hoge(); result = "hello"; } }; Assert.assertEquals("hello", new Foo().hoge()); } @Test public void hoge2() { new NonStrictExpectations() { Bar bar; Baz baz; { bar.baz(); result = baz; times=1; baz.hoge(); result = "hello"; times=1; } }; Assert.assertEquals("hello", new Foo().hoge()); }JMockit を使い始めたばかりだと、結構、とまどうんじゃないかと思う。デバッガで追ってみると、例えば "result = baz" のところで、初期化していないはずの baz に何故かインスタンスが設定されているし、代入されたと思った result が null のままだったりして、普通の Java ソースの感覚で読んでいると訳が分からなかったりする。
とは言ってもまあ、すぐ慣れるし、そうなると逆に、JMockit 無しのテストを考える事が、時折難しく感じられてくる。
ただ、JMockit を使うと後付けテストもかなり簡単になるにはなるけど、やっぱりテストファーストが基本というのは押さえておいた方が良い。この例はもともと簡単だから、それほど大変なテストコードにはならないけど、もっと複雑なものになると、後付けとテストファーストではテストコーディングの生産性が大きく違ってくる。
====
テストファースト版は、こっちに書いた。
0 件のコメント:
コメントを投稿