【Java】【Mockit】モックメソッドの引数と呼び出し回数の検証
本記事ではJUnitでのテストの中でMockitを使ってモック化したメソッドの呼び出し回数と呼び出し時に渡された引数の値を検証する方法を紹介します。
準備
検証環境
動作検証を行った環境は以下の通りです。
- Java 21
- Spring Boot 3.2.7
テスト対象
本記事では購入額と会員ランクから獲得ポイントを計算してDBに保存する処理をテスト対象とします。下図のようにPointServiceクラスをテスト対象とし、DBアクセスを行うPointRepositoryクラスをMockitoでモック化します。
PointServiceクラスとPointRepositoryクラスのソースコードは以下のように作成します。
PointServiceクラス
PointRepositoryクラスを使用しDBから顧客IDに紐づくポイント還元率を取得し、獲得ポイントを計算しDBへ保存します。
// パッケージ、インポートは省略
@RequiredArgsConstructor
@Service
public class PointService {
private final PointRepository pointRepository;
public BigDecimal calculateAndSavePoint(int customerId, BigDecimal purchaseAmount) {
// 顧客IDからポイント還元率を取得
var pointRate = pointRepository.getPointRate(customerId);
// 獲得ポイントを計算
var earnedPoint = purchaseAmount.multiply(pointRate);
// 獲得ポイントを保存
return pointRepository.savePoint(customerId, earnedPoint);
}
}
PointRepositoryクラス
DBアクセスを行うリポジトリクラスのインターフェースです。
// パッケージ、インポートは省略
public interface PointRepository {
BigDecimal getPointRate(int customerId);
BigDecimal savePoint(int customerId, BigDecimal point);
}
PointRepositoryImplクラス
PointRepositoryの実装クラスです。未完成の状態を想定して各メソッドの処理は記述していません。
// パッケージ、インポートは省略
@Repository
public class PointRepositoryImpl implements PointRepository {
@Override
public BigDecimal getPointRate(int customerId) {
return null;
}
@Override
public BigDecimal savePoint(int customerId, BigDecimal point) {
return null;
}
}
テストコード
以下のようなテストコードを作成しました。このテストコードではPointRepositoryをモック化し、saveメソッドの実行回数と渡された引数を検証しています。
verifyメソッドを使用することでモック化したメソッドの呼び出し回数を検証することができます。実行回数はtimesメソッドを使って指定できます。
ArgumentCaptureクラスを使用することでモック化したメソッドに渡された引数の値を取得できます。値を検証したい引数ごとにArgumentCaptureクラスのインスタンスを作成します。
ArgumentCaptureクラスのインスタンスからgetValueメソッドを呼び出すことでメソッド実行時の引数の値を取得できます。取得した値をassertThatを使って検証しています。
// パッケージ、インポートは省略
@ExtendWith(MockitoExtension.class)
class PointServiceTest {
@InjectMocks
private PointService pointService;
@Mock
private PointRepository pointRepository;
@Test
public void test1() {
// PointRepositoryクラスのgetPointRateメソッドは 0.01 を返すようにモック化する
Mockito.when(pointRepository.getPointRate(Mockito.anyInt())).thenReturn(new BigDecimal("0.01"));
// PointRepositoryクラスのsaveメソッドは 10.00 を返すようにモック化する
Mockito.when(pointRepository.savePoint(Mockito.anyInt(), Mockito.any())).thenReturn(new BigDecimal("10.00"));
// PointServiceクラスのテストを実施
pointService.calculateAndSavePoint(10, new BigDecimal("1000"));
// PointRepositoryクラスのsaveメソッド呼び出し回数を検証
var customerIdCaptor = ArgumentCaptor.forClass(Integer.class);
var earnedPointCapture= ArgumentCaptor.forClass(BigDecimal.class);
verify(pointRepository, times(1)).savePoint(customerIdCaptor.capture(), earnedPointCapture.capture());
// PointRepositoryクラスのsaveメソッドの呼び出し時の引数を検証
var customerId = customerIdCaptor.getValue();
var capturedPoint = earnedPointCapture.getValue();
assertThat(customerId).isEqualTo(10);
assertThat(capturedPoint).isEqualTo(new BigDecimal("10.00"));
}
}
この記事ではSpring Bootで作成したプロジェクト内でMockitを使ってモック化する方法と、モック化したメソッドに対する引数、モック化したメソッドの呼び出し方法を検証する方法を紹介しました。
また、ソフトウェアテストの手法やテストの進め方については【この1冊でよくわかる】ソフトウェアテストの教科書で分かりやすく解説されています。