参考資料はこれ → 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 件のコメント:
コメントを投稿