メモ: テスト対象メソッドの実行後、テストメソッドは即座に終了される
昨日の続き。というより、訂正です。
- メモ: JUnitのexpectedフィールドとRuleアノテーションで例外のテスト http://d.hatena.ne.jp/torazuka/20121002/junit
JUnitのRuleアノテーションの使い方を知って喜んでいましたが、1つのテストメソッドの中では、1回だけしかテスト対象コードの呼び出しを書いてはいけなかったようです。
コメントで教えていただきました(ありがとうございます)。昨日の記事のテストコードは、修正済みです。
たとえば、次のコードを実行すると・・・
import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; public class DeckTest { Deck deck; @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void testDivideCardsForException() throws Exception { // ※注 このテストメソッドは、よくない例 deck = new Deck(); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("山札は1枚以上なければならない。"); System.out.println("hoge"); // (1) deck.divideCards(0, 2); // 1回目のテスト対象コードの呼び出し thrown.expect(IllegalArgumentException.class); thrown.expectMessage("プレイヤー数は2以上でなければならない。"); System.out.println("moga"); // (2) deck.divideCards(2, 0); // 2回目のテスト対象コードの呼び出し } }
テストはグリーンになって成功します。
しかし、標準出力を見ると、
hoge
1回目のテスト対象メソッドの呼び出ししか、評価されていないことが分かります。
ちなみに、テスト対象メソッドの呼び出しの直前と直後にメッセージを出力すると、
@Test public void testDivideCardsForDeckException() throws Exception { deck = new Deck(); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("山札は1枚以上なければならない。"); System.out.println("hoge"); // (1) deck.divideCards(0, 2); // テスト対象コードの呼び出し System.out.println("moga"); // (2) }
直前のメッセージだけが表示されます。
hoge
テスト対象コードの呼び出しまでしか実行されないのですね。
JUnit先生のRunnerの動きをよく理解していませんでした。
というわけで、ExpectExceptionがどんなふうに実行されるのか少し見てみようと思って、テスト対象メソッドの呼び出しにブレークポイントを置き、ひとまずデバッグ実行してみました。
ReflectiveCallable.runメソッドから、ExpectedException.evaluateメソッド、RanRules.evaluateメソッドが呼び出されます。ここで、あらかじめ設定しておいた例外の型や、メッセージ文字列が、Matcherを使って確認されます。
確認が終わったら、ParentRunner.runLeafのfinalyブロックに入ります。(ここまで実行してきたのが、tryブロックにあるstatement.evaluate()だったんですね)
try { statement.evaluate(); } catch (AssumptionViolatedException e) { eachNotifier.addFailedAssumption(e); } catch (Throwable e) { eachNotifier.addFailure(e); } finally { eachNotifier.fireTestFinished(); }
fireTestFinishedメソッドは、RunNotifierのメソッドです。「Invoke to tell listeners that an atomic test finished. 」というJavadocコメントがありました。
new SafeNotifier() { @Override protected void notifyListener(RunListener each) throws Exception { each.testFinished(description); }; }.run();
例外を調査したら、さっさと実行を終えてしまうらしいことだけは、分かりました。
本当はもっと詳しく読んでみるべきところですが、今日はここまで(^^;