При тестировании функции Spring Cloud Stream бин канала вывода Spring Cloud Contract не является org.springframework.messaging.PollableChannel - PullRequest
0 голосов
/ 09 марта 2020

Я пытаюсь создать Spring Cloud Contract для проверки сообщений при использовании Spring Cloud Stream. Я включил зависимости в pom. xml

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
<!--TEST-->
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-test-support</artifactId>
        <scope>test</scope>
</dependency>
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-contract-verifier</artifactId>
        <scope>test</scope>
</dependency>
<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream</artifactId>
        <type>test-jar</type>
        <scope>test</scope>
        <classifier>test-binder</classifier>
</dependency>

и настроил плагин контрактов

 <!-- Contracts -->
 <plugin>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-contract-maven-plugin</artifactId>
        <version>${spring-cloud-contract.version}</version>
        <extensions>true</extensions>
        <configuration>
           <baseClassForTests>com.example.streams.kafkastreamer.KafkaStreamerApplicationTests
           </baseClassForTests>
        </configuration>
 </plugin>

Затем я локально запустил простое приложение, чтобы проверить, что все работает как положено. Однако после создания теста Spring Cloud Contract, следуя документации , я получаю следующую ошибку при выполнении сгенерированного теста

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'uppercase-out-0' is expected to be of type 'org.springframework.messaging.PollableChannel' but was actually of type 'org.springframework.cloud.stream.messaging.DirectWithAttributesChannel'

Я проверил, что созданный тест выглядит как один в документации, и он вроде как делает это для меня

@Test
public void validate_consume() throws Exception {
    // given:
        ContractVerifierMessage inputMessage = contractVerifierMessaging.create(
                "[\"MIAU\"]"
                    , headers()
                        .header("sample", "header")
        );

    // when:
        contractVerifierMessaging.send(inputMessage, "uppercase-in-0");

    // then:
        ContractVerifierMessage response = contractVerifierMessaging.receive("uppercase-out-0");
        assertThat(response).isNotNull();

    // and:
        assertThat(response.getHeader("contentType")).isNotNull();
        assertThat(response.getHeader("contentType").toString()).isEqualTo("application/json");

    // and:
        DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload()));
        assertThatJson(parsedJson).field("['attributes']").field("['id']").isEqualTo("com.example.streams.kafkastreamer.KafkaStreamerApplication$$EnhancerBySpringCGLIB$$cf6cc14c2020-03-05T12:07:05.366");
        assertThatJson(parsedJson).field("['attributes']").field("['source']").isEqualTo("file:///com/example/streams/kafkastreamer");
        assertThatJson(parsedJson).field("['attributes']").field("['specversion']").isEqualTo("1.0");
        assertThatJson(parsedJson).field("['attributes']").field("['type']").isEqualTo("My.test.event.type");
        assertThatJson(parsedJson).field("['attributes']").field("['datacontenttype']").isEqualTo("application/json");
        assertThatJson(parsedJson).field("['attributes']").field("['dataschema']").isNull();
        assertThatJson(parsedJson).field("['attributes']").field("['subject']").isNull();
        assertThatJson(parsedJson).field("['attributes']").field("['time']").isNull();
        assertThatJson(parsedJson).field("['data']").field("['value']").isEqualTo("MIAU");
        assertThatJson(parsedJson).field("['dataBase64']").isNull();
        assertThatJson(parsedJson).field("['extensions']").field("['specversion']").isEqualTo("1.0");
        assertThatJson(parsedJson).array("['extensionsFormats']").isEmpty();
}

В образце документации Spring Cloud Contract используется jms, и канал установлен как sentTo('jms:output'). Поскольку я использую связыватель Spring Cloud Stream Binder, я устанавливаю название канала в соответствии с определением моего связывателя как sentTo('uppercase-out-0'). Вот свойства моего приложения

#stubrunner.integration.enabled: false To make sure is using Spring Cloud Stream
spring.cloud.stream.bindings.uppercase-in-0.destination=test
spring.cloud.stream.bindings.uppercase-in-0.group=testGroup
spring.cloud.stream.bindings.uppercase-out-0.destination=hood
spring.cloud.stream.bindings.consume-in-0.destination=hood
spring.cloud.stream.bindings.consume-out-0.destination=downtown
spring.cloud.function.definition=uppercase;consume

Мой вопрос: Почему канал в верхнем регистре 0 не реализует требуемый PollableChannel ? Наверное, я неправильно понял что-то из официальной документации Spring Cloud Stream или Spring Cloud Contract, но не могу понять, что.

Еще немного информации. Я предполагаю, что автоконфигурация настраивает bean-компонент типа SpringIntegrationSubMessages, но должен быть StreamStubMessages. Однако я не знаю, как и почему это происходит. Я правильно угадываю?

1 Ответ

0 голосов
/ 10 марта 2020

Проблема исходила из конфигурации моего родительского тестового класса. В какой-то момент моя среда разработки предложила мне добавить компонентное сканирование, потому что не было найдено bean-компонента для

@Autowired
private MessageVerifier verifier;

, поэтому я добавил @ComponentScan(basePackages={"org.springframework.cloud.contract.verifier.messaging"}) и в итоге инициализировал некоторые bean-компоненты, которые делали условные bean-компоненты в ContractVerifierStreamAutoConfiguration неконфигурированными , но SpringIntegrationSubMessages. Обнаружил, что при проверке, что в официальной документации нет @ComponentScan, и я очистил свой код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...