Тестирование потока весенней интеграции с использованием Http.outboundGateway() с настроенной табличкой RestTemplate

#mockito #spring-integration #junit5 #spring-test

Вопрос:

У меня есть ситуация, когда я пишу модульные тесты для потока интеграции, который зависит от конфигурации RestTemplate , выполняющей аутентификацию.

 @Configuration
public class XXIntegrationConfig {
    @Autowired
    private RestTemplate restTemplate;

    @Bean
    public IntegrationFlow readRemote() {
        return f ->
            f.handle(
                Http.outboundGateway("http://localhost:8080/main/{mainId}", restTemplate)
                    .httpMethod(HttpMethod.GET)
                    .uriVariable("mainId", "headers.mainId")
                    .expectedResponseType(String.class)
            )
            .transformers(Transformers.fromJson())
            .enrich(enrichSecondary())
            .transform(Transformers.toJson());
    }

    @Bean
    public Consumer<EnricherSpec> enrichSecondary() {
        return e ->
            e.requestSubFlow(
                esf -> esf.handle(
                    Http.outboundGateway("http://localhost:8080/main/{mainId}/secondary", restTemplate)
                        .httpMethod(HttpMethod.GET)
                        .uriVariable("mainId", "headers.mainId")
                        .mappedResponseHeaders()
                        .expectedResponseType(String.class)
                )
                .transform(Transformers.fromJson())
            )
            .propertyExpression("secondary", "payload.value");
    }
}
 

У меня возникли трудности с установлением теста, в котором restTemplate это @Autowired является издевательством.

Я попробовал что-то похожее на следующее, но безуспешно

 @SpringBootTest
@SpringIntegrationTest
public class XXIntegrationConfigTests {
    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    @Autowired
    private XXIntegrationConfig xxIntegrationConfig;

    @Autowired
    private IntegrationFlowContext integrationFlowContext;

    @Test
    public void testEnrichSecondary() {
        when(restTemplate.exchange(..... arg matchers ....)).thenReturn(
              new ResponseEntity("test document", HttpStatus.OK)
        );

        final Consumer<EnricherSpec> enrichSecondary = xxIntegrationConfig.enrichSecondary();
        IntegrationFlow flow =
            f -> f.enrich(enrichSecondary());
        IntegrationFlowContext.IntegrationFlowRegistration flowRegistration =
            integrationFlowContext.registration(flow).register();

        final Message<?> request =
                MessageBuilder.withPayload(new HashMap<String,Object>())
                        .setHeader("mainId", "xx-001")
                        .build();

        Message<?> response = 
                flowRegistration.getMessagingTemplate().sendAndReceive(request); 
    }
}
 

Это тестирование, по-видимому, не переопределяет введенный RestTemplate в класс config до того, как будут созданы компоненты XXIntegrationConfig .

Любые мысли по этому поводу были бы весьма признательны.

Ответ №1:

Смотрите «Весенний ботинок @MockBean «: https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.testing.spring-boot-applications.mocking-beans. Итак, все, что вам нужно, это просто отметить свое RestTemplate свойство в тесте с помощью этой аннотации, и Spring Boot позаботится о его внедрении в ожидаемые конфигурации.

Комментарии:

1. Как всегда волшебник! Попробую сделать это в ближайшее время.

2. Работает как чемпион — теперь я должен выяснить соответствие параметров — еще раз спасибо!

3. Выяснил соответствие — работает именно так, как я и ожидал! — Еще раз спасибо вам!