unit-test-exception-handler は何をしますか?
Spring Bootアプリケーションにおける@ExceptionHandlerおよび@ControllerAdviceのユニットテストパターンを提供します。エラーレスポンスのフォーマット検証、例外のモック化、HTTPステータスコードの確認、フィールドレベルのバリデーションエラー、カスタムエラーペイロードのアサーションを行います。Spring例外ハンドラのテスト、REST APIエラーテスト、コントローラアドバイスのモック化にご利用ください。
概要
このプロジェクトは、Spring Bootアプリケーションにおける例外ハンドリングのテストを簡素化します。共通のユニットテストパターンを提供し、開発者が@ExceptionHandlerと@ControllerAdviceの動作を効果的に検証できるようにします。
主な機能
- 例外モック化: テスト対象となる例外を簡単にモック化し、さまざまなシナリオをシミュレートします。
- HTTPステータスコード検証:
@ExceptionHandlerメソッドが正しいHTTPステータスコードを返すかを確認します。 - エラーレスポンスフォーマット検証: エラーレスポンスが期待される構造とフィールドを持っているかをテストします。
- フィールドレベルのバリデーション:
@Validatedや@NotNullなどのアノテーションによるフィールドバリデーションエラーをテストします。 - カスタムエラーペイロードアサーション: カスタムエラーペイロード(エラーコード、メッセージ、タイムスタンプなど)の内容をアサートします。
前提条件
- Java 8以上
- Spring Boot 2.x以上
- テストフレームワーク(JUnit 5推奨)
- Mockito(モック化用)
インストール方法
Maven
<dependency>
<groupId>com.example</groupId>
<artifactId>unit-test-exception-handler</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
Gradle
testImplementation 'com.example:unit-test-exception-handler:1.0.0'
使用例
基本的な例外ハンドラテスト
以下の例は、@ControllerAdviceで定義された例外ハンドラのテスト方法を示します。
@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = YourController.class)
class ExceptionHandlerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testNotFoundException() throws Exception {
mockMvc.perform(get("/api/resource/1"))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.message").value("Resource not found"))
.andExpect(jsonPath("$.status").value(404));
}
}
バリデーションエラーのテスト
@Test
void testValidationError() throws Exception {
String invalidRequestBody = "{\"name\": \"\"}";
mockMvc.perform(post("/api/resource")
.contentType(MediaType.APPLICATION_JSON)
.content(invalidRequestBody))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errors[0].field").value("name"))
.andExpect(jsonPath("$.errors[0].message").value("must not be blank"));
}
カスタムエラーペイロードのアサーション
@Test
void testCustomErrorPayload() throws Exception {
mockMvc.perform(get("/api/resource/error"))
.andExpect(status().isInternalServerError())
.andExpect(jsonPath("$.errorCode").value("INTERNAL_ERROR"))
.andExpect(jsonPath("$.timestamp").exists());
}
テストパターン
1. 単一例外ハンドラのテスト
特定の例外に対する@ExceptionHandlerメソッドをテストします。
2. 複数例外ハンドラのテスト
@ExceptionHandlerが複数の例外タイプを処理する場合のテスト。
3. グローバル例外ハンドラのテスト
@ControllerAdviceで定義されたグローバルな例外ハンドラをテストします。
4. レスポンスエンティティテスト
ResponseEntityを返す例外ハンドラのテスト。
設定
テスト設定ファイル(例:application-test.properties)に以下を追加することで、テスト環境に特化した設定が可能です。
# テスト用のエラーレスポンスフォーマット
app.error.include-stack-trace=false
よくある質問(FAQ)
Q: テストで例外がスローされない場合はどうすればよいですか?
A: Mockitoのwhenを使用して、サービスやリポジトリが特定の例外をスローするようにモック化します。
Q: カスタム例外クラスを作成する必要がありますか?
A: いいえ、既存の例外クラス(例:ResourceNotFoundException)をモック化することも、テスト用にカスタム例外を作成することもできます。
注意事項
- テストコードはプロダクションコードと同様にメンテナンスが必要です。
@WebMvcTestはコントローラ層のみをテストするため、サービス層のモック化が必要な場合があります。- エラーレスポンスの構造はAPIドキュメントと一致していることを確認してください。
コントリビューション
バグ報告や機能リクエストは、GitHubのイシュートラッカーをご利用ください。プルリクエストも歓迎します。
ライセンス
このプロジェクトはMITライセンスの下で公開されています。詳細はLICENSEファイルを参照してください。