minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

jMockは、JUnitによるユニットテストで使うツールです。

モックオブジェクト

モックオブジェクトとは一体何でしょうか。

簡単に言うと、あるインスタンスの動作を代行するものです。

public class Sample {

  private External external;

  public void some() {
    ...
    external.someExternal(...);
    ...
  }
  
  public void setExternal(External external) {
    this.external = external;
  }
}

こんなコードがあったとします。
ここでSampleクラスのユニットテスト(以下UT)を書くとしましょう。

モックを使わない方法だと、例えば以下のようになります。

public void SampleTest {

  @Test
  public void testSome() {
    Sample sample = new Sample();
    
    External external = new External(...);
    external.init();
    sample.setExternal();
    
    sample.some();
    ...
  }
  
}

このように、実際にsomeメソッドを呼び出すときと同じように
Externalインスタンスを生成してそれを渡しています。

これはこれで一つの手段なのですが、いくつかの問題点があります。

このような欠点を解決するための一つの手法が、モックオブジェクトです。
上の例で言うと、Externalインスタンスを通常通り作成するのではなく
「ダミーの」Externalインスタンスを作成します。

こうすることによって、Externalクラスの変更があっても
SampleのUTは変更する必要が無くなります。
また、本来のExternalクラスは一切使わないので
テスト範囲が広がることもありません。

モックとインターフェイス

ここで一つ重要な点があります。
モックで使用するインスタンスは必ずインターフェイス化されていなければなりません。
先程の例で言うと、Externalクラスではなく
Externalインターフェイスを用意する必要があるという事になります。

もしExternalがクラスだと、そのモックオブジェクトを作るためには
以下のような感じになってしまいます。

public MockExternal extends External {
  @Override
  public void sumeExternal() {
    ...
  }
}

このように、全てのpublicメソッドをオーバーライドして
実装する必要が出てきてしまいます。
こういうモックオブジェクトは過去には実際使われてきた手法なのですが
非常に手間が掛かりコードが汚くなる為に、あまり好ましくない手法なのです。

Externalをインターフェイスにすると、以下のような感じになります。

public interface External {
  void sumeExternal();
}

public class ExternalImpl implements External {
  public void sumeExternal() {
    ...
  }
}

モックオブジェクトおよびテストコードは以下のような記述になります。

public class MockExternal implements External {
  public void sumeExternal() {
    ...
  }
}
public void SampleTest {

  @Test
  public void testSome() {
    Sample sample = new Sample();
    
    External external = new MockExternal();
    sample.setExternal();
    
    sample.some();
    ...
  }
}

これで、MockExternal は External には依存していますが
メインの実装である ExternalImpl からは完全に独立しています。
モックを実装から独立させる。
これがインターフェイスを使う最大の理由です。

jMockの場合

さて、前置きが長くなりましたが。
jMockとは、このモックオブジェクトを
より簡単に使うための便利ツールです。

以下では、実際にjMockを使ってテストコードの書き方を紹介していきます。