unit-test-mapper-converter について
MapStructのマッパーやカスタムコンバーターの単体テストを作成する開発者向けスキルです。マッピング精度、null処理、ネストや双方向変換などを扱います。
主な機能
- 01フィールドと型のマッピングテスト
- 02null処理の確認
- 03ネストおよび双方向マッピングの検証
- 04列挙型とコレクション変換のテスト
- 05カスタムマッピング式の検証
活用シーン
- 01MapStruct生成マッパー実装のテスト
- 02エンティティからDTOへの変換動作の確認
- 03ネストしたオブジェクトとコレクションの検証
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ giuseppe-trisciuoglio/ developer-kit --skill unit-test-mapper-converterインストール後、Claude Code で/unit-test-mapper-converterを入力して読み込まれたか確認します。
同梱ファイルreferences/examples.md
詳細
マッパーとコンバーターのユニットテスト
概要
MapStruct のマッパーとカスタムコンバータークラスをユニットテストするためのパターンを紹介します。フィールドマッピングの正確性、null の処理、型変換、ネストされたオブジェクトの変換、双方向マッピング、列挙型マッピング、部分更新を扱います。
使用する場面
- MapStruct マッパーの実装に対するマッピングテストを書く場合
- カスタムのエンティティから DTO へのコンバーターと Bean マッピングをテストする場合
- ネストされたオブジェクトのマッピングとコレクション変換を検証する場合
手順
1. 生成されたマッパークラスを検証する
テストを実行する前に、生成されたマッパークラスが存在することを確認します。
# Maven
ls target/generated-sources/
# Gradle
ls build/generated/sources/
生成されたクラスが見つからない場合:
mvn compile(Maven)または./gradlew compileJava(Gradle)を実行します- MapStruct のアノテーションプロセッサーが設定されていることを確認します
@Mapperインターフェースがコンパイル対象のソースセットに含まれていることを確認します
2. null の処理をテストする
assertThat(mapper.toDto(null)).isNull();
null の場合に空またはデフォルト値を返す必要があれば、マッパーで nullValueMappingStrategy を設定します。
null のテストが失敗する場合:
@MapperにnullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULLを追加します- または、ネストされたプロパティの処理には
nullValuePropertyMappingStrategyを使用します
3. 双方向マッピングをテストする
User restored = mapper.toEntity(mapper.toDto(original));
assertThat(restored).usingRecursiveComparison().isEqualTo(original);
双方向マッピングのテストが失敗する場合:
@Mappingアノテーションでフィールド名が一致していることを確認します- 自動マッピングが失敗する場合は、両方の方向が明示的にマッピングされていることを確認します
- マッピング漏れを検出するには、
unmappedTargetPolicy = ReportingPolicy.ERRORを使用します
4. ネストされたオブジェクトのマッピングをテストする
assertThat(dto.getNested()).usingRecursiveComparison().isEqualTo(expected);
ネストのテストが失敗する場合:
- ネストされたマッパーが存在するか、
uses = NestedMapper.classで参照されていることを確認します elementMappingStrategyでコレクション要素のマッピングを確認します
5. カスタム式をテストする
@Mapping(target = "field", expression = "java(...)") のカスタム式は、コンパイル時に検証されません。
式のテストが失敗する場合:
- 式の構文とメソッドシグネチャを確認します
- インポートしたクラスに式のコンテキストからアクセスできることを確認します
6. 列挙型マッピングをテストする
列挙型から列挙型への変換には @ValueMapping を使用します。すべての列挙値を漏れなくテストします。
ベストプラクティス
- 単独のテストには
Mappers.getMapper()を使用し、統合テストには Spring のインジェクションを使用します - 複雑なネスト構造には
usingRecursiveComparison()を使用します - コレクション変換を含む、すべてのマッパーメソッドをテストします
- null 許容のすべてのソースフィールドについて、null の処理を検証します
- 双方向マッピングをテストして、エンティティ→DTO と DTO→エンティティ間の非対称性を検出します
- マッパーテストは、実装の詳細ではなく変換の正確性に焦点を絞ります
制約と警告
- コンパイル時の生成:MapStruct はコンパイル時にコードを生成します。テスト実行前に、生成されたクラスが存在することを確認してください
- null の処理:
nullValueMappingStrategyとnullValuePropertyMappingStrategyを適切に設定してください - 式の検証:
@Mappingの式はコンパイル時に検証されないため、明示的にテストしてください - 循環依存関係:MapStruct はマッパー間の循環依存関係を処理できません
- コレクションの不変性:不変コレクションのマッピングには、特別な設定が必要な場合があります
- 日付/時刻:タイムゾーンをまたいで日付/時刻オブジェクトが正しくマッピングされることを確認してください
例
インポートを含む、完全に実行可能なテスト:
package com.example.mapper;
import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers;
import static org.assertj.core.api.Assertions.*;
class UserMapperCompleteTest {
private final UserMapper mapper = Mappers.getMapper(UserMapper.class);
@Test
void shouldMapUserToDto() {
User user = new User(1L, "Alice", "[email protected]", 25);
UserDto dto = mapper.toDto(user);
assertThat(dto)
.isNotNull()
.extracting(UserDto::getName, UserDto::getEmail)
.containsExactly("Alice", "[email protected]");
}
@Test
void shouldMaintainRoundTrip() {
User original = new User(1L, "Alice", "[email protected]", 25);
assertThat(mapper.toEntity(mapper.toDto(original)))
.usingRecursiveComparison()
.isEqualTo(original);
}
@Test
void shouldHandleNullInput() {
assertThat(mapper.toDto(null)).isNull();
}
}
その他の例:references/examples.md
コメント
Markdown 対応