[英]How to use constructor injection in Mapstruct's mapper?
In some mapper classes, I need to use an autowired ObjectMapper to transform String
to JsonNode
or verse-vera.在某些映射器类中,我需要使用自动装配的 ObjectMapper 将
String
转换为JsonNode
或 verse-vera。 I can acheive my goal by using the field injection with @autowired
.我可以通过使用带有
@autowired
的字段注入来实现我的目标。 But it's not suitable for unit test so I'd like to try using the constructor injection.但它不适合单元测试所以我想尝试使用构造函数注入。
My current working code with the field injection:我当前使用字段注入的工作代码:
@Mapper(componentModel = "spring")
public class CustomMapper {
@autowired
ObjectMapper mapper;
}
I try to convert it to the constructor injection so I can provide constructor argument in my unit test:我尝试将其转换为构造函数注入,以便我可以在单元测试中提供构造函数参数:
@Mapper(componentModel = "spring")
public class CustomMapper {
ObjectMapper mapper;
public CustomMapper(ObjectMapper mapper) {
this.mapper = mapper;
}
}
But I get a Constructor in CustomMapper cannot be applied to the given type
error during compilation.但是我在编译期间
Constructor in CustomMapper cannot be applied to the given type
得到一个Constructor in CustomMapper cannot be applied to the given type
错误。 How do I fix it?我如何解决它? Or is there other better way to map
String
to JsonNode
in Mapstruct?或者还有其他更好的方法将
String
映射到JsonNode
中的 JsonNode 吗?
Constructor injection cannot be used in the mapper definition.不能在映射器定义中使用构造函数注入。 Only in the mapper implementation.
仅在映射器实现中。
However, for unit testing I'd suggest that you use setter injection.但是,对于单元测试,我建议您使用 setter 注入。
Your mapper will then look like:您的映射器将如下所示:
@Mapper( componentModel = "spring")
public class CustomMapper {
protected ObjectMapper mapper;
@Autowired
public void setMapper(ObjectMapper mapper) {
this.mapper = mapper;
}
}
1)The MapStruct has good feature: 1)MapStruct 有很好的特性:
@Mapper(componentModel = "spring", uses ={ObjectMapper.class}, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
2)You could do it this way: 2)你可以这样做:
@Mapper(componentModel = "spring")
@RequiredArgsConstructor //lombok annotation, which authowire your field via constructor
public class CustomMapper {
private final ObjectMapper mapper;
}
But still you could do it via field.You stiil should mock it in tests in both cases.但是你仍然可以通过 field.You 来做到这一点。在这两种情况下,你都应该在测试中模拟它。 Just remember to use
@InjectMocks
请记住使用
@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());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.