返回
MapStruct映射器内映射器的注入:解决单元测试无法访问默认方法
java
2024-03-11 19:48:44
MapStruct映射器内的映射器注入
问题
当你使用MapStruct将实体对象映射到领域对象时,你可能会遇到一个场景,其中实体对象包含一个包含另一类型列表的字段。为了映射此列表,你需要在主映射器内部使用另一个映射器。但是,在单元测试期间,你可能会发现无法访问默认映射器方法,因为它们不在实现类中。
解决方案
要解决此问题,你可以使用以下步骤:
-
创建自定义映射器接口
首先,创建一个自定义映射器接口,它将定义你的默认映射方法。此接口将由主映射器实现。
public interface CustomMapper { List<DomainB> mapList(List<EntityB> entityB); }
-
在主映射器中实现自定义映射器
在你的主映射器中,使用
@Named
注释将你的默认映射方法与自定义映射器接口中的方法连接起来。@Mapping(target = "listOfDomainB", source = "entityA.list", qualifiedByName = "mapList") DomainA map(EntityA entityA); @Override default List<DomainB> mapList(List<EntityB> entityB) { return entityB.stream() .map(EntityB -> new EntityB() .name(EntityB.getName())) .collect(Collectors.toList()); }
-
使用代理创建自定义映射器的实例
在你的服务类中,使用代理创建自定义映射器接口的实例。这将允许你在单元测试中模拟映射器的方法。
private final CustomMapper customMapper = Mapper.withContext(Collections.singletonMap(DestinationType.class, type)) .getMapper(CustomMapper.class);
常见问题解答
1. 为什么在实现类中调用默认方法时,映射器模拟的.toCallRealMethod()不会调用mapList
?
这是因为代理会在实现类中创建一个接口的动态实现,该实现类调用默认方法。当执行
.toCallRealMethod()
时,它不会调用实现类,而是调用代理类,该类不包含默认方法。
2. 是否可以使用其他方法来解决此问题?
除了使用自定义映射器接口,你还可以考虑使用
@Context
或@Qualifier
注释来注入映射器。但是,这些方法可能更复杂或更难维护。
3. 我在哪里可以找到更多关于MapStruct映射器注入的信息?
有关MapStruct映射器注入的更多信息,你可以参考MapStruct文档:
结论
通过使用自定义映射器接口和代理,你可以轻松地解决MapStruct映射器内映射器的注入问题。这将使你能够模拟映射器方法并编写更可靠的单元测试。