参考資料はこれ → Behavior-based testing with JMockit
====
まずこんなコードから始めてみる。Swing に限らず、GUI フレークワークの入門書の最初に出てくるような、何もないウィンドウを単に開いてみるだけのもの。
public class Exercise1 { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(500, 300); frame.setVisible(true); } }
要するに 500×300のウィンドウがビジブルになれば良い訳で、以下のようなテストコードになる。
public class Exercise1Test { @Test public void main() { new Expectations() { @NonStrict JFrame frame; { frame.setSize(500, 300);times=1; frame.setVisible(true);times=1; }}; Exercise1.main(new String[]{}); } }
ここで、ウィンドウのクローズイベントに対応するアプリケーション終了処理が無い事に気づき、例えば、以下のように追加したとする。
public static void main(String[] args) { JFrame frame = new JFrame(); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(500, 300); frame.setVisible(true); }この無名クラスを含むコードをどうやってテストするか。
以下のような方針をとってみた。
- System クラスをパーシャルモックして、exit(0) 呼び出しを expect する(変な日本語だが…)。
- 無名インナークラスについては、次のようにする。
- addWindowListener に渡された、WindowListener を保持しておく。
- main() 実行の後で、保持しておいた WindowListener のwindowClosing()を明示的に呼び出す。
コードはこんな感じ。
public class Exercise1Test2 { @Mocked({"exit"}) System system; static class WindowListenerCapturer implements Delegate { WindowListener captured; void addWindowListener(WindowListener l) { captured = l; }; } @Test public void main() { final WindowListenerCapturer delegate = new WindowListenerCapturer(); new Expectations() { @NonStrict JFrame frame; { frame.addWindowListener((WindowListener)any); result = delegate; frame.setSize(500, 300);times=1; frame.setVisible(true);times=1; }}; new Expectations() {{ System.exit(0); }}; Exercise1.main(new String[]{}); delegate.captured.windowClosing(null); } }
ここでは、実際の実行パスの流れと同じになるように、main() からの Expectation と、windowClosing() からの Expectation を分けて書いてみた。
WindowListenerCapturer を使わないで、result = new Delegate() { ... }として、「...」のところで、windowClosing() を呼ぶやり方も試してみたが、何故か Eclipse プラグインがテスト終了を認識しない。
まあ上で示したコードでも、キャプチャのためのコードが若干増えることになるとはいえ、実行時の流れを表していると言う点では、却って分かりやすいような気もする。
0 件のコメント:
コメントを投稿