モックフレームワークJMockitで実行時にクラスを差し替える

テストをしたいのに連携システムが起動していなくて単体でのテストができませんでした。テストをしにくいという設計上の問題点はおいといて、他システムと連携する部分をモックで差し替えて動かせないものかと、Javaのモックフレームワークを調べると、EasyMock, JMock, Mockitなどが検索でヒットします。djUnitもモックフレームワークの一種でしょうか。調べた中で一番使いやすそうだったJMockitについてのメモを書いておきます。引数によってモッククラスの挙動を変更する、というのが他のモックフレームワークでは難しそうでした。


JMockitのページはこちら。
Google Code Archive - Long-term storage for Google Code Project Hosting.
Java 1.5以上で動くようです。ダウンロードしたらクラスパスにjmockit.jarを追加します。1.5で動かす場合はVMの引数に -javaagent:jmockit.jar を指定する必要があります。


サンプルコード

モック対象のクラス。


public class SayHello {

public String echo(String s) {
return "Hello!";
}
}


モック。SayHelloをこのクラスで差し替えます。


import mockit.*;

@MockClass(realClass=SayHello.class)
public class MockSayHello {

@Mock
public String echo(String s) {
return s;
}
}

MockClassアノテーションでモッククラスであることを定義し、属性のrealClassでモック対象のクラスを指定します。Mockアノテーションでモックメソッドであることを定義します。


サンプルのメインクラス。


public class MockSampleRunner {

public static void main(String[] args) {
Mockit.setUpMock(MockSayHello.class);

SayHello obj = new SayHello();
System.out.println(obj.echo("Mocked echo"));
}
}

モックを実行する前にMockitクラスのstaticメソッド
public static void setUpMocks(Object... mockClassesOrInstances)
でモッククラスを設定する必要があります。

実行結果

Mocked echo


SayHello.echo() の振る舞いがモッククラスによって差し替えられています。