torutkのブログ

ソフトウェア・エンジニアのブログ

Mockito + PowerMockを使ってみる

JMockitと同様、ユニットテスト対象のクラスが、別なクラスのstaticメソッドを呼んでインスタンスを取得し、そのインスタンスのメソッドを呼び出し、その戻り値によってロジックが左右されるという場合のテストを想定します。

テスト対象クラスは、JMockitと同じものを使います。

Mockito + PowerMockを使ってJUnitでテストを書くと

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import static org.powermock.api.mockito.PowerMockito.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(SensorFactory.class)
public class ThresholdMonitorTest {

    @Test
    public void testSenseAlarm() {
        mockStatic(SensorFactory.class);
        WeatherSensor mockSensor = mock(WeatherSensor.class);
        when(SensorFactory.getWeatherSensor()).thenReturn(mockSensor);
        when(mockSensor.getTemperature()).thenReturn(30.5);

        ThresholdMonitor instance = new ThresholdMonitor();
        boolean result = instance.sense();
        assertEquals(false, result);
    }
}

Mockito+PowerMockの場合、テストクラスへのアノテーションとして、

  • @RunWith(PowerMockRunner.class)
  • @PrepareForTest(特殊なモック対象クラス,...)

が必要です。前者は、PowerMockがバイトコード・インストゥルメントするための記述で、後者は、staticメソッドやfinalクラスをモック化する際に必要です(少しずれているかも)。

staticメソッドを持つクラスをモック化するために、mockStaticを使用します。インスタンスとして利用するクラスはモック化にはmockを使用します。ここでも、インタフェースに対してmockを呼び出してモック生成することができました。

モックの振る舞いを定義するには、whenを用いて、()内に振る舞いを定義するメソッド呼び出し式を記述します。続いて、thenReturnを用いてメソッドのモックとして振る舞う戻り値を定義します。

モックの定義をした後は、普通にJUnitのテスト記述を行います。

インストール

Mockito+PowerMockの場合、PowerMockサイトダウンロードページから、"powermock-mockito-junit-バージョン番号"のファイルをダウンロードします。これを展開し、中に含まれるjarファイルをクラスパスに含めます。
現時点の最新バージョンであるPowerMock 1.4.5の場合、以下のJARをクラスパスに指定します。

  • powermock-mockito-1.4.5-full.jar
  • mockit-all-1.8.5.jar
  • javassist-3.13.0.GA.jar