You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+MapStruct+JUnit:服务测试中注入Mapper而非Stub

解决方案:在Spring Boot单元测试中使用真实MapStruct实现

一、纯单元测试(不加载Spring上下文,推荐)

这是单元测试的最优方案,无需启动Spring容器,直接使用真实Mapper实例:

1. 确保MapStruct在测试编译阶段生成实现类

检查pom.xml的注解处理器配置,确保测试阶段也能生成Mapper实现:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>11</source> <!-- 替换为你的JDK版本 -->
                <target>11</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>1.5.3.Final</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>你的Lombok版本</version>
                    </path>
                    <!-- 可选:解决Lombok与MapStruct的兼容性问题 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>0.2.0</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

2. 测试类直接实例化真实Mapper与服务类

利用Mappers.getMapper()获取真实Mapper实例,结合Mockito Mock其他依赖,直接创建服务类:

import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.mapstruct.factory.Mappers;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class StandardReservationServiceTest {

    @Mock
    private ReservationRepository reservationRepositoryMock;

    @Mock
    private ReservationRulesRepository reservationRulesRepositoryMock;

    // 真实的MapStruct实现实例
    private final ReservationMapper reservationMapper = Mappers.getMapper(ReservationMapper.class);

    // 直接构造服务类,传入真实Mapper和Mock依赖
    private final StandardReservationService service = new StandardReservationService(
            reservationMapper,
            reservationRepositoryMock,
            reservationRulesRepositoryMock
    );

    @ParameterizedTest
    @EnumSource(ReservationSource.class)
    public void yourTestMethod(ReservationSource source) {
        // 编写测试逻辑
    }
}

二、集成测试(加载Spring上下文)

如果必须使用Spring容器,按以下方式修改:

1. 测试类配置

不要直接引用编译时生成的ReservationMapperImpl(编译前不存在,会导致clean报错),直接引用Mapper接口,Spring会自动扫描并注入其实现类:

@SpringBootTest(classes = {StandardReservationService.class, ReservationMapper.class})
public class StandardReservationServiceTest {

    @MockBean
    private ReservationRepository reservationRepositoryMock;

    @MockBean
    private ReservationRulesRepository reservationRulesRepositoryMock;

    @Autowired
    private ReservationMapper reservationMapper; // 真实的Mapper实现

    @Autowired
    private StandardReservationService service;

    // 测试方法...
}

2. 关键注意事项

  • 确保Mapper接口所在包在Spring的扫描范围内
  • 执行mvn clean compile后,检查target/generated-sources/annotations目录下是否生成了ReservationMapperImpl类,确认注解处理器工作正常

常见问题排查

  • IDE中找不到ReservationMapperImpl:开启IntelliJ的「Enable annotation processing」(设置→Build, Execution, Deployment→Compiler→Annotation Processors)
  • Maven编译报错找不到Impl:检查注解处理器配置是否完整,执行mvn clean test-compile验证测试阶段的代码生成

内容的提问来源于stack exchange,提问作者Yass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:50:24