1. 概要

モッキングフレームワークは、依存関係との相互作用をモックして、クラスを分離してテストするために使用されます。 通常、依存関係をモックして、さまざまな可能な値を返します。 このようにして、クラスがこれらの各値を処理できるようにすることができます。

ただし、何も返さない依存関係メソッドをモックする必要がある場合があります。

このチュートリアルでは、EasyMockを使用してvoidメソッドをいつどのようにモックするかを確認します。

2. Mavenの依存関係

まず、EasyMock依存関係pom.xmlに追加しましょう。

<dependency>
    <groupId>org.easymock</groupId>
    <artifactId>easymock</artifactId>
    <version>4.0.2</version>
    <scope>test</scope>
</dependency>

3. voidメソッドをモックするタイミング

依存関係のあるクラスをテストする場合、通常、依存関係によって返されるすべての値をカバーする必要があります。 ただし、依存関係メソッドが値を返さない場合があります。 では、何も返されない場合、なぜvoidメソッドをモックしたいのでしょうか?

voidメソッドは値を返しませんが、 それらには副作用があるかもしれません。  この例は Session.save() 方法。 新しいエンティティを保存すると、 save()メソッドがIDを生成し、渡されたエンティティに設定します。

このため、さまざまな処理結果をシミュレートするには、voidメソッドをモックする必要があります。

モッキングが役立つもう1つの場合は、voidメソッドによってスローされた例外をテストする場合です。

4. voidメソッドをモックする方法

それでは、EasyMockを使用してvoidメソッドをモックする方法を見てみましょう。

ある場所を取得して最低気温と最高気温を設定するWeatherServiceクラスのvoidメソッドをモックする必要があるとします。

public interface WeatherService {
    void populateTemperature(Location location);
}

4.1. モックオブジェクトの作成

WeatherServiceのモックを作成することから始めましょう。

@Mock
private WeatherService mockWeatherService;

ここでは、EasyMockアノテーション@Mockを使用してこれを行いました。 ただし、 EasyMock.mock()メソッドを使用してこれを行うこともできます。

次に、 populateTemperature()を呼び出して、モックとの予想される相互作用を記録します。

mockWeatherService.populateTemperature(EasyMock.anyObject(Location.class));

ここで、このメソッドの処理をシミュレートしたくない場合は、この呼び出し自体でメソッドをモックするのに十分です。

4.2. 例外をスローする

まず、voidメソッドによってスローされた例外をクラスが処理できるかどうかをテストする場合を考えてみましょう。 このためには、これらの例外をスローするようにメソッドをモックする必要があります。

この例では、メソッドはServiceUnavailableExceptionをスローします。

EasyMock.expectLastCall().andThrow(new ServiceUnavailableException());

上記のように、これには andThrow(Throwable)メソッドを呼び出すだけです。

4.3. メソッドの動作のシミュレーション

前述のように、voidメソッドの動作をシミュレートする必要がある場合があります。

私たちの場合、これには、通過した場所の最低気温と最高気温を入力することが含まれます。

EasyMock.expectLastCall()
  .andAnswer(() -> {
      Location passedLocation = (Location) EasyMock.getCurrentArguments()[0];
      passedLocation.setMaximumTemparature(new BigDecimal(MAX_TEMP));
      passedLocation.setMinimumTemperature(new BigDecimal(MAX_TEMP - 10));
      return null;
  });

ここでは、 andAnswer(IAnswer)メソッドを使用して、呼び出されたときの populateTemperature()メソッドの動作を定義しました。 次に、 EasyMock.getCurrentArguments()メソッド(モックメソッドに渡された引数を返す)を使用して、渡された場所を変更しました。

最後にがnullを返したことに注意してください。これは、voidメソッドをモックしているためです。

このアプローチは、voidメソッドのモックのみに限定されないことにも注意してください。 値を返すメソッドにも使用できます。 そこで、渡された引数に基づいて値を返すようにメソッドをモックしたい場合に便利です。

4.4. モックメソッドの再生

最後に、 EasyMock.replay()メソッドを使用して、モックを「再生」モードに変更し、呼び出されたときに記録されたアクションを再生できるようにします。

EasyMock.replay(mockWeatherService);

したがって、テストメソッドを呼び出すときは、定義されたカスタム動作を実行する必要があります。

5. 結論

このチュートリアルでは、EasyMockを使用してvoidメソッドをモックする方法を説明しました。

そしてもちろん、この記事で使用されているコードは、GitHubにあります。