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

能否让带装饰器的MapStruct Mapper同时成为@Component并支持单元测试?

带装饰器的MapStruct Mapper:同时支持单元测试与Spring注入的问题

现有配置说明

单元测试场景配置

要对带装饰器的Mapper进行单元测试,需使用以下配置:

@Mapper(componentModel = "default")
@DecoratedWith(CardMapperDecorator.class)
public interface CardMapper {
public abstract class CardMapperDecorator implements CardMapper {

    private CardMapper delegate;

    public CardMapperDecorator(CardMapper delegate) {
        this.delegate = delegate;
    }

Spring组件场景配置

要让带装饰器的Mapper成为@Component供Spring容器管理并注入,需使用以下配置(注:MapStruct无法在生成的实现类中创建包含super调用的构造方法,因此需采用Setter注入方式):

@Mapper(componentModel = "spring")
@DecoratedWith(CardMapperDecorator.class)
public interface CardMapper {
@Component
public abstract class CardMapperDecorator implements CardMapper {

    private CardMapper delegate;

    @Autowired // 也可直接对字段添加@Autowired注解
    public void setDelegate(CardMapper delegate) {
        this.delegate = delegate;
    }

核心需求

能否实现同时满足单元测试(无需启动Spring上下文)和作为Spring组件供其他Bean注入的场景?

尝试方案及问题

根据M. Deinum的建议,尝试为装饰器类添加额外构造方法,但该方案未生效,运行时触发SonarQube报错:

尝试的配置代码

装饰器类:

@Component
@NoArgsConstructor
public abstract class CardMapperDecorator implements CardMapper {
    @Autowired
    private CardMapper delegate; // 用于Spring注入

    public CardMapperDecorator(CardMapper delegate) { // 用于单元测试的默认注入
        this.delegate = delegate;
    }
// 装饰器逻辑

Mapper接口:

@Mapper(componentModel = "default") // 此配置是单元测试不启动Spring上下文的关键
@DecoratedWith(CardMapperDecorator.class)
public interface CardMapper {

// 映射方法定义

报错信息

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'by.afinny.credit.mapper.CardMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:30:03