はじめに
Javaで開発を行う際、クラス単位・メソッド単位での 単体テスト(ユニットテスト) は、品質を高めるために必要になってきます。
特に、Spring Bootなどで開発していると、Service
クラスやRepository
クラスなどに分離されていることが多く、依存関係の切り離しが重要になってきます。
そこで役立つのが、Mockitoというライブラリです。
本記事では、サービスクラスの単体テストを行う際に、Mockitoを使ってリポジトリなどの依存クラスをモック化する方法について解説します。
使用ライブラリ・フレームワーク
- JUnit 5(テストフレームワーク)
- Mockito(モックライブラリ)
なぜモックが必要なのか?
単体テストでは、テスト対象のクラス以外の処理に依存せず、純粋にそのクラスの振る舞いのみを検証することが理想です。
例えば、サービスクラスをテストしたい場合、本来はその中で呼ばれているリポジトリの動作も同時に動いてしまいます。
しかし、それではテストの範囲が広がりすぎて、エラーの原因や関心所が分かりにくくなるという問題があります。
そのため、リポジトリのような他クラスの振る舞いをモック(仮の動作)に置き換えることで、テスト対象を明確に絞ることができます。
例:サービスクラスのテスト
以下は、ユーザーを検索するサービスクラスと、その単体テストの例です。
1. テスト対象のServiceクラス
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("User not found"));
}
}
2. Mockitoを使ったテストクラス
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void testFindUserById_success() {
// モックとして返したいUserデータを作成
User mockUser = new User(1L, "Taro");
// userRepository.findByIdが呼ばれたときにmockUserを返すよう設定
when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser));
// 実際にServiceメソッドを呼ぶ
User result = userService.findUserById(1L);
// 結果を検証
assertEquals("Taro", result.getName());
}
}
よく使うMockitoのメソッド
メソッド | 説明 |
---|---|
@Mock |
モックとして使いたいクラスに付与 |
@InjectMocks |
モックを注入する対象に付与 |
when(...).thenReturn(...) |
特定のメソッドが呼ばれたときの戻り値を定義 |
verify(...) |
メソッドの呼び出し回数などを検証 |
doThrow(...).when(...) |
例外を投げるよう設定 |
まとめ
- JUnit + Mockitoを使えば、対象クラスだけに注目したテストが可能になる
- サービスクラスの単体テストでは、リポジトリなどの依存クラスをモック化するのが基本
-
when(...).thenReturn(...)
を使って、リポジトリの戻り値を自由に設定できる
おわりに
単体テストを丁寧に書くことで、新規開発のバグの検知につながったり、将来的な修正の安心感にもつながります。
JUnit + Mockitoをしっかり使いこなして、堅牢なコードを目指しましょう。