Messaging

Spring Cloud Contract 允许您验证使用消息传递作为通信方式的应用程序。本文档中显示的所有集成都适用于 Spring,但您也可以创建自己的集成并使用。

Messaging DSL Top-level Elements

消息传递的 DSL 看起来与专注于 HTTP 的 DSL 有点不同。以下部分解释了差异:

Output Triggered by a Method

输出消息可以通过调用一个方法(例如,在启动合约和发送消息时调用的 Scheduler)来触发,如下例所示:

Groovy
Unresolved directive in project-features-messaging.adoc - include::{tests_path}/samples-messaging-integration/src/test/groovy/com/example/IntegrationMessagingApplicationSpec.groovy[]
YAML
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/resources/yml/contract_message_method.yml[]

在前面的示例情况下,如果调用名为 bookReturnedTriggered 的方法,则输出消息将发送到 output。在消息发布者的方面,我们生成一个测试来调用该方法以触发消息。在消费者方面,可以使用 some_label 来触发消息。

Consumer/Producer

此部分仅对 Groovy DSL 有效。

在 HTTP 中,您有 client/stub 和 `server/test 符号的概念。您还可以在消息传递中使用这些范例。此外,Spring Cloud Contract Verifier 还提供 consumerproducer 方法(请注意,您可以使用 $value 方法来提供 consumerproducer 部分)。

Common

inputoutputMessage 段中,你可以使用已在 base 类或静态导入中定义的 method 名称(例如,assertThatMessageIsOnTheQueue())来调用 assertThat。Spring Cloud Contract 在生成的测试中运行该方法。

Integrations

你可以使用以下集成配置之一:

  • Apache Camel

  • Spring Integration

  • Spring Cloud Stream

  • Spring JMS

由于我们使用 Spring Boot,所以如果你已将其中一个库添加到类路径,则会自动设置所有消息传递配置。

请记住在生成测试的基本类上添加 @AutoConfigureMessageVerifier。否则,Spring Cloud Contract 的消息部分将无法正常工作。

如果你想使用 Spring Cloud Stream,请务必添加对 org.springframework.cloud:spring-cloud-stream 的测试依赖项,如下所示:

Maven
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream</artifactId>
    <type>test-jar</type>
    <scope>test</scope>
    <classifier>test-binder</classifier>
</dependency>
Gradle
testImplementation(group: 'org.springframework.cloud', name: 'spring-cloud-stream', classifier: 'test-binder')

Manual Integration Testing

测试使用的主要接口是 org.springframework.cloud.contract.verifier.messaging.MessageVerifierSenderorg.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver。它定义如何发送和接收消息。

在测试中,你可以注入 ContractVerifierMessageExchange 以发送和接收符合契约的消息。然后向测试添加 @AutoConfigureMessageVerifier。以下示例演示如何执行此操作:

@RunWith(SpringTestRunner.class)
@SpringBootTest
@AutoConfigureMessageVerifier
public static class MessagingContractTests {

  @Autowired
  private MessageVerifier verifier;
  ...
}

如果您的测试也需要存根,则 @AutoConfigureStubRunner 包含了消息传递配置,因此您只需要一个注释。

Producer Side Messaging Test Generation

在 DSL 中具有 inputoutputMessage 段将导致在发布方一侧创建测试。默认情况下,会创建 JUnit 4 测试。但是,也可以创建 JUnit 5、TestNG 或 Spock 测试。

传递给 messageFromsentTo 的目标对于不同的消息传递实现可能具有不同的含义。对于 Stream 和集成,它首先解析为 通道的 destination。然后,如果不存在 destination,则将其解析为一个通道名称。对于 Camel,那是一个特定组件(例如 jms)。

考虑以下契约:

Groovy
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[]
YAML
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/resources/yml/contract_message_scenario1.yml[]

对于前面的示例,将创建以下测试:

JUnit
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[]
Spock
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[]

Consumer Stub Generation

与 HTTP 部分不同,在消息传递中,我们需要在 JAR 内发布契约定义,并附带存根。然后在消费者一侧解析它,并创建适当的存根路由。

如果您的类路径上有多个框架,则 Stub Runner 需要定义应使用哪一个。假设您在类路径上有 AMQP、Spring Cloud Stream 和 Spring Integration,并且您要使用 Spring AMQP。然后您需要设置 stubrunner.stream.enabled=falsestubrunner.integration.enabled=false。以这种方式,唯一剩下的框架是 Spring AMQP。

Stub triggering

要触发消息,请使用 StubTrigger 接口,如下面的示例所示:

Unresolved directive in project-features-messaging.adoc - include::{stubrunner_core_path}/src/main/java/org/springframework/cloud/contract/stubrunner/StubTrigger.java[]

为方便起见,StubFinder 接口扩展了 StubTrigger,所以你只需在测试中使用其中之一。

StubTrigger 为你提供了以下触发消息的选项:

Trigger by Label

下面的示例演示如何使用标签触发消息:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

Trigger by Group and Artifact IDs

下面的示例演示如何按组和制品 ID 触发消息:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

Trigger by Artifact IDs

下面的示例演示如何从制品 ID 触发消息:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

Trigger All Messages

下面的示例演示如何触发所有消息:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

Consumer Side Messaging With Apache Camel

Spring Cloud Contract Stub Runner 的消息传递模块为你提供了一种与 Apache Camel 集成的简单方法。对于提供的制品,它会自动下载存根并注册所需的路由。

Adding Apache Camel to the Project

你可以在类路径上同时拥有 Apache Camel 和 Spring Cloud Contract Stub Runner。请务必用 @AutoConfigureStubRunner 为你的测试类添加注释。

Disabling the Functionality

如果你需要禁用此功能,请设置 stubrunner.camel.enabled=false 属性。

Examples

假设我们有以下 Maven 存储库,其中部署了 camelService 应用程序的存根:

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── camelService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── camelService-0.0.1-SNAPSHOT.pom
                            │   ├── camelService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

此外,还要假设存根包含以下结构:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   └── bookReturned1.groovy
    └── mappings

现在考虑以下契约:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/samples-messaging-camel/src/test/groovy/com/example/CamelMessagingApplicationSpec.groovy[]

为了从 return_book_1 标签触发消息,我们使用 StubTrigger 接口,如下所示:

stubFinder.trigger("return_book_1")

这将向契约输出消息中描述的目标发送一条消息。

Consumer Side Messaging with Spring Integration

Spring Cloud Contract Stub Runner 的消息传递模块提供了一种轻松的方式来与 Spring Integration 集成。对于提供的制品,它会自动下载存根并注册所需的路由。

Adding the Runner to the Project

你可以在类路径上同时拥有 Spring Integration 和 Spring Cloud Contract Stub Runner。别忘了使用 @AutoConfigureStubRunner 为你的测试类加注释。

Disabling the Functionality

如果你需要禁用此功能,请设置 stubrunner.integration.enabled=false 属性。

Examples

假设我们有以下 Maven 存储库,其中部署了 integrationService 应用程序的存根:

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── integrationService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── integrationService-0.0.1-SNAPSHOT.pom
                            │   ├── integrationService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

此外,还要假设存根包含以下结构:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   └── bookReturned1.groovy
    └── mappings

考虑以下契约:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[]

现在考虑以下 Spring Integration 路由:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml[]

为了从 return_book_1 标签触发消息,请使用 StubTrigger 接口,如下所示:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[]

这将向契约输出消息中描述的目标发送一条消息。

Consumer Side Messaging With Spring Cloud Stream

Spring Cloud Contract Stub Runner 的消息传递模块提供了一种轻松的方式来与 Spring Stream 集成。对于提供的制品,它会自动下载存根并注册所需的路由。

如果 Stub Runner 与 Stream messageFromsentTo 字符串的集成首先解析为 通道 destination,并且不存在此 destination,则目标解析为通道名称。

如果你想要使用 Spring Cloud Stream,别忘了添加对 org.springframework.cloud:spring-cloud-stream 测试支持的依赖项,如下所示:

Maven
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-stream-test-binder</artifactId>
    <scope>test</scope>
</dependency>
Gradle
testImplementation('org.springframework.cloud:spring-cloud-stream-test-binder')

Adding the Runner to the Project

你可以在类路径上同时拥有 Spring Cloud Stream 和 Spring Cloud Contract Stub Runner。别忘了使用 @AutoConfigureStubRunner 为你的测试类加注释。

Disabling the Functionality

如果你需要禁用此功能,请设置 stubrunner.stream.enabled=false 属性。

Examples

假设我们有以下 Maven 存储库,其中部署了 streamService 应用程序的存根:

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── streamService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── streamService-0.0.1-SNAPSHOT.pom
                            │   ├── streamService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

此外,还要假设存根包含以下结构:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   └── bookReturned1.groovy
    └── mappings

考虑以下契约:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

现在考虑以下 Spring Cloud Stream 函数配置:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

现在考虑以下 Spring 配置:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml[]

为了从 return_book_1 标签触发消息,请使用 StubTrigger 接口,如下所示:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[]

这将向契约输出消息中描述的目标发送一条消息。

Consumer Side Messaging With Spring JMS

Spring Cloud Contract Stub Runner 的消息模块提供了一种轻松集成 Spring JMS 的方法。

集成要求您运行 JMS 代理实例。

Adding the Runner to the Project

您需要同时将 Spring JMS 和 Spring Cloud Contract Stub Runner 放入类路径。请务必使用 @AutoConfigureStubRunner 为您的测试类添加注解。

Examples

假设存根结构如下所示:

├── stubs
    └── bookReturned1.groovy

此外,假设有以下测试配置:

stubrunner:
  repository-root: stubs:classpath:/stubs/
  ids: my:stubs
  stubs-mode: remote
spring:
  activemq:
    send-timeout: 1000
  jms:
    template:
      receive-timeout: 1000

现在考虑以下契约:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy[]

为了从 return_book_1 标签触发消息,我们使用 StubTrigger 接口,如下所示:

Unresolved directive in project-features-messaging.adoc - include::{tests_path}/spring-cloud-contract-stub-runner-jms/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/jms/JmsStubRunnerSpec.groovy[]

这将向契约输出消息中描述的目标发送一条消息。