能否让带装饰器的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
相关产品推荐
相关产品推荐

