アノテーションを利用したモックの作成

テストケースのフィールドに@Mockアノテーションを付与しておくことでモックオブジェクトを生成することができる。ただしこの場合、以下のようにMockitoAnnotations.initMocks(this);を呼び出す必要がある。テストケースの基底クラスで実行するようにしておくといいだろう。

public class CalculatorTest {
  @Mock
  private ItemDao mock;

  @Before
  public void initMocks() {
    MockitoAnnotations.initMocks(this);
  }
  ...   
}

モックの設定方法を理解する

Mockitoを使いこなすには、モックの挙動の設定方法を理解する必要がある。ここでは少し複雑なパターンでのモックの設定例を見てみよう。

まずは最もシンプルな例だ。以下のコードは「findItem()を引数=1で呼び出した場合にItemオブジェクトを返却する」という意味になる。

when(mock.findItem(1))
  .thenReturn(new Item(1, "Eclipseプラグイン開発徹底攻略", 3900));

引数を問わずに同じ結果を返したい場合には以下のようにanyInt()などを指定する。この他にも引数のマッチングを行うための様々なメソッドが用意されている。冒頭でも説明したとおり、MockitoクラスのメンバーをstaticインポートしておけばIDE上での入力補完が可能なので、いろいろと試してみるといいだろう。

when(mock.findItem(anyInt()))
  .thenReturn(new Item(1, "Eclipseプラグイン開発徹底攻略", 3900));

戻り値や例外の定義はチェーンさせることができる。以下のように設定すると1度目の呼び出しではItemオブジェクトを返却し、2度目の呼び出しでは例外がスローされる。

when(mock.findItem(anyInt()))
  .thenReturn(new Item(1, "Eclipseプラグイン開発徹底攻略", 3900))
  .thenThrow(new IllegalArgumentException("商品が存在しません。"));

まとめ - 扱いやすさNo.1のモックライブラリ

Mockitoは数あるJava向けのモックライブラリの中でも群を抜いて扱いやすい。staticインポートとメソッドチェーンを活用した構文は最近ではそれほど珍しいものではなくなったが、他のモックライブラリと比べると自然に記述することができ、テストケースも読みやすい。

また、モックライブラリの中にはメソッドの戻り値などを指定する際にメソッド名を文字列で指定しなければならないものも多い。こういったモックライブラリを使用する場合、IDEのリファクタリング機能を利用して元のクラスをリファクタリングしてメソッド名など変わった場合にテストケースが通らなくなってしまう。Mockitoではメソッドの指定含めタイプセーフに記述できるため、リファクタリングにも強いテストケースを記述することができる。

Javaのモックライブラリにはさまざまなものがあるが、どれを使おうか迷っているのであればMockitoを試してみるといいだろう。なお、MockitoにはPython版Flex版も存在する。いずれも本稿で紹介したJava版と同じ感覚で使用することができる。PythonやFlexの開発者も要注目のライブラリといえそうだ。