Как использовать инжектор конструктора в картографе Mapstruct? - PullRequest
0 голосов
/ 20 февраля 2020

В некоторых классах мапперов мне нужно использовать AutoMired 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 с JsonNode в Mapstruct?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

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;
}

Но все же вы можете сделать это через поле. высмеивать это в тестах в обоих случаях. Просто не забудьте использовать @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());
   }
}
0 голосов
/ 20 февраля 2020

Внедрение в конструктор не может использоваться в определении картографа. Только в реализации картографа.

Однако для модульного тестирования я бы предложил использовать инъекцию сеттера.

Ваш картограф будет выглядеть так:

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

    protected ObjectMapper mapper;


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

} 
...