如何在 Mapstruct 的映射器中使用构造函数注入?

How to use constructor injection in Mapstruct's mapper?

在某些映射器 类 中,我需要使用自动装配的 ObjectMapper 将 String 转换为 JsonNode 或 verse-vera。我可以通过使用带 @autowired 的字段注入来实现我的目标。但它不适合单元测试所以我想尝试使用构造函数注入。

我当前使用字段注入的工作代码:

@Mapper(componentModel = "spring")
public class CustomMapper {
  @autowired
  ObjectMapper mapper;
}

我尝试将其转换为构造函数注入,以便我可以在我的单元测试中提供构造函数参数:

@Mapper(componentModel = "spring")
public class CustomMapper {
  ObjectMapper mapper;

  public CustomMapper(ObjectMapper mapper) {
    this.mapper = mapper;
  }
}

但是我在编译过程中遇到 Constructor in CustomMapper cannot be applied to the given type 错误。 我如何解决它?还是有其他更好的方法将 String 映射到 Mapstruct 中的 JsonNode

映射器定义中不能使用构造函数注入。仅在映射器实现中。

但是,对于单元测试,我建议您使用 setter 注入。

您的映射器将如下所示:

@Mapper( componentModel = "spring") 
public class CustomMapper {

    protected ObjectMapper mapper;


    @Autowired
    public void setMapper(ObjectMapper mapper) {
        this.mapper = mapper;
   } 

} 

1)MapStruct有很好的特性:

@Mapper(componentModel = "spring", uses ={ObjectMapper.class}, injectionStrategy = InjectionStrategy.CONSTRUCTOR)

2)你可以这样做:

@Mapper(componentModel = "spring")
@RequiredArgsConstructor //lombok annotation, which authowire your field via constructor
public class CustomMapper {
  private final ObjectMapper mapper;
}

但是您仍然可以通过 field.You 完成这两种情况的测试。请记住使用 @InjectMocks

public CustomMapperTest {
   @InjectMocks
   private CustomMapper customMapper;
   @Mock
   private ObjectMapper objectMapper

   @BeforeEach
   void setUp() {
      customMapper= new CustomMapperImpl();
      MockitoAnnotations.initMocks(this);
      when(objectMapper.map()).thenReturn(object);
   }

   @Test
   void shouldMap() {
      Object toObject = customerMapper.map(fromObject);
      assertThat(toObject)
        .hasFieldWithValue("fieldName", fromObject.getField());
   }
}