mcpField
U
unit-test-mapper-converter

unit-test-mapper-converter

github.com/giuseppe-trisciuoglio测试与质量3653.7k 次安装7 周前更新
代码仓库

关于 unit-test-mapper-converter

面向开发者的测试技能,用于为 MapStruct 映射器和自定义转换器编写单元测试,涵盖映射准确性、空值处理、嵌套及双向转换等场景。

主要功能

  1. 01测试字段与类型映射
  2. 02检查空值处理
  3. 03覆盖嵌套与双向映射
  4. 04测试枚举和集合转换
  5. 05验证自定义映射表达式

适用场景

  1. 01测试 MapStruct 生成的映射器实现
  2. 02验证实体到 DTO 的转换器行为
  3. 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 映射器和自定义转换器类的单元测试模式。涵盖字段映射准确性、空值处理、类型转换、嵌套对象转换、双向映射、枚举映射和部分更新。

使用场景

  • 为 MapStruct 映射器实现编写映射测试
  • 测试自定义实体到 DTO 的转换器和 Bean 映射
  • 验证嵌套对象映射和集合转换

说明

1. 验证生成的映射器类

测试前,确认生成的映射器类存在:

# Maven
ls target/generated-sources/

# Gradle
ls build/generated/sources/

如果缺少生成的类:

  1. 运行 mvn compile(Maven)或 ./gradlew compileJava(Gradle)
  2. 检查是否已配置 MapStruct 注解处理器
  3. 确认 @Mapper 接口位于已编译的源代码集中
2. 测试空值处理
assertThat(mapper.toDto(null)).isNull();

如果空值应返回空对象或默认值,请在映射器中配置 nullValueMappingStrategy。

如果空值测试失败:

  1. 将 nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL 添加到 @Mapper
  2. 或使用 nullValuePropertyMappingStrategy 处理嵌套属性
3. 测试双向映射
User restored = mapper.toEntity(mapper.toDto(original));
assertThat(restored).usingRecursiveComparison().isEqualTo(original);

如果双向映射测试失败:

  1. 检查 @Mapping 注解中的字段名称是否不匹配
  2. 如果自动映射失败,请确认已显式映射两个方向
  3. 使用 unmappedTargetPolicy = ReportingPolicy.ERROR 捕获缺失的映射
4. 测试嵌套对象映射
assertThat(dto.getNested()).usingRecursiveComparison().isEqualTo(expected);

如果嵌套对象测试失败:

  1. 确保存在嵌套映射器,或通过 uses = NestedMapper.class 引用它
  2. 使用 elementMappingStrategy 检查集合元素映射
5. 测试自定义表达式

@Mapping(target = "field", expression = "java(...)") 中的自定义表达式不会在编译时验证。

如果表达式测试失败:

  1. 检查表达式语法和方法签名
  2. 确认表达式上下文可以访问导入的类
6. 测试枚举映射

使用 @ValueMapping 转换枚举。全面测试所有枚举值。

最佳实践

  • 独立测试使用 Mappers.getMapper(),集成测试使用 Spring 注入
  • 对复杂嵌套结构使用 usingRecursiveComparison()
  • 测试所有映射器方法,包括集合转换
  • 验证所有可空源字段的空值处理
  • 测试双向映射,以捕获实体→DTO 和 DTO→实体之间的不对称
  • 让映射器测试聚焦于转换正确性,而非实现细节

限制和警告

  • 编译时生成:MapStruct 在编译时生成代码;运行测试前请确认生成的类存在
  • 空值处理:适当配置 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