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

在IntelliJ中测试Spring Boot 3集成MapStruct遇Bean缺失问题

Spring Boot 3 + MapStruct 测试时出现NoSuchBeanDefinitionException的解决办法

问题背景

我在IntelliJ中测试一个返回DTO的Spring Boot 3控制器(用MapStruct做对象转换),主项目编译正常,但测试时一直抛出异常:

NoSuchBeanDefinitionException: No qualifying bean of type <my mapper type>

已做的配置操作:

  • 编写测试配置类尝试扫描Mapper包,但无效:
@TestConfiguration
@ComponentScan(basePackageClasses = EntityMapper.class)
public class MapperConfig {}
  • 测试类注解配置:
@ExtendWith(SpringExtension.class)
@WebMvcTest({SiteController.class, MapperConfig.class})
public class SiteControllerTests { .... }
  • Gradle依赖配置:
dependencies {
    implementation 'org.mapstruct:mapstruct:1.5.5.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
    ...
}
  • IntelliJ设置:启用「Enable annotation processing」,设置「Obtain processors from classpath」,MapStruct依赖设为Provided,已安装MapStruct插件,项目同时使用Lombok。

更新:Mapper定义
父接口:

public interface EntityMapper<D, E> {

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "createdAt", ignore = true)
    @Mapping(target = "updatedAt", ignore = true)
    void updateEntityFromDto(@MappingTarget E entity, D dto);

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "createdAt", ignore = true)
    @Mapping(target = "updatedAt", ignore = true)
    E fromDto(D dto);

    @Mapping(target = "id", ignore = true)
    @Mapping(target = "createdAt", ignore = true)
    @Mapping(target = "updatedAt", ignore = true)
    List<E> fromDto(List<D> dtoList);

    D toDto(E entity);

    List<D> toDto(List<E> entityList);
}

具体业务Mapper:

@Mapper(componentModel = "spring")
public interface SiteMapper extends EntityMapper<SiteDto, Site> {

    @Override
    @Mapping(source = "user.id", target = "userId")
    SiteDto toDto(Site site);

    @Override
    // 避免覆盖已有信息
    @Mapping(target = "id", ignore = true)
    @Mapping(target = "createdAt", ignore = true)
    @Mapping(target = "updatedAt", ignore = true)
    @Mapping(target = "user", ignore = true)
    void updateEntityFromDto(@MappingTarget Site site, SiteDto siteDTO);
}

解决步骤

1. 修正测试配置类的扫描范围

你的MapperConfig用EntityMapper.class作为扫描基准,但EntityMapper是父接口,MapStruct自动生成的Spring Bean是SiteMapperImpl,正确的扫描基准应该是实际带@Mapper注解的SiteMapper.class:

@TestConfiguration
@ComponentScan(basePackageClasses = SiteMapper.class)
public class MapperConfig {}

2. 直接在测试类导入Mapper Bean

@WebMvcTest默认只加载控制器相关Bean,不会自动扫描MapStruct生成的实现类。可以直接在测试类用@Import导入目标Mapper:

@ExtendWith(SpringExtension.class)
@WebMvcTest(SiteController.class)
@Import(SiteMapper.class)
public class SiteControllerTests { .... }

3. 协调Lombok与MapStruct的注解处理器顺序

同时使用Lombok时,必须确保MapStruct处理器在Lombok之后执行,Gradle中补充配置:

dependencies {
    // 原有依赖
    implementation 'org.mapstruct:mapstruct:1.5.5.Final'
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
    // 添加绑定依赖
    annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'
}

tasks.withType(JavaCompile) {
    options.annotationProcessorPath = configurations.annotationProcessor
    options.compilerArgs += [
        '-Amapstruct.defaultComponentModel=spring',
        '-Alombok.mapstruct.binding.enabled=true'
    ]
}

4. 调整IntelliJ的依赖与注解处理设置

  • 取消将MapStruct依赖设为Provided,测试时需要该依赖在类路径中
  • 执行./gradlew clean build,确认MapStruct生成的SiteMapperImpl类出现在build/classes/java/main目录下
  • 检查IntelliJ的「Annotation Processors」设置,确保「Processor path」选择「Module output」

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:23:09