Messaging
Spring Cloud Contract 允许您验证使用消息传递作为通信方式的应用程序。本文档中显示的所有集成都适用于 Spring,但您也可以创建自己的集成并使用。
Messaging DSL Top-level Elements
消息传递的 DSL 看起来与专注于 HTTP 的 DSL 有点不同。以下部分解释了差异:
Output Triggered by a Method
输出消息可以通过调用一个方法(例如,在启动合约和发送消息时调用的 Scheduler
)来触发,如下例所示:
Unresolved directive in project-features-messaging.adoc - include::{tests_path}/samples-messaging-integration/src/test/groovy/com/example/IntegrationMessagingApplicationSpec.groovy[]
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/resources/yml/contract_message_method.yml[]
在前面的示例情况下,如果调用名为 bookReturnedTriggered
的方法,则输出消息将发送到 output
。在消息发布者的方面,我们生成一个测试来调用该方法以触发消息。在消费者方面,可以使用 some_label
来触发消息。
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
的测试依赖项,如下所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<type>test-jar</type>
<scope>test</scope>
<classifier>test-binder</classifier>
</dependency>
testImplementation(group: 'org.springframework.cloud', name: 'spring-cloud-stream', classifier: 'test-binder')
Manual Integration Testing
测试使用的主要接口是 org.springframework.cloud.contract.verifier.messaging.MessageVerifierSender
和 org.springframework.cloud.contract.verifier.messaging.MessageVerifierReceiver
。它定义如何发送和接收消息。
在测试中,你可以注入 ContractVerifierMessageExchange
以发送和接收符合契约的消息。然后向测试添加 @AutoConfigureMessageVerifier
。以下示例演示如何执行此操作:
@RunWith(SpringTestRunner.class)
@SpringBootTest
@AutoConfigureMessageVerifier
public static class MessagingContractTests {
@Autowired
private MessageVerifier verifier;
...
}
如果您的测试也需要存根,则 |
Producer Side Messaging Test Generation
在 DSL 中具有 input
或 outputMessage
段将导致在发布方一侧创建测试。默认情况下,会创建 JUnit 4 测试。但是,也可以创建 JUnit 5、TestNG 或 Spock 测试。
传递给 messageFrom
或 sentTo
的目标对于不同的消息传递实现可能具有不同的含义。对于 Stream 和集成,它首先解析为 通道的 destination
。然后,如果不存在 destination
,则将其解析为一个通道名称。对于 Camel,那是一个特定组件(例如 jms
)。
考虑以下契约:
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[]
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/resources/yml/contract_message_scenario1.yml[]
对于前面的示例,将创建以下测试:
Unresolved directive in project-features-messaging.adoc - include::{verifier_root_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[]
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=false
和 stubrunner.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[]
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
为你的测试类添加注释。
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
为你的测试类加注释。
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 messageFrom
或 sentTo
字符串的集成首先解析为 通道 destination
,并且不存在此 destination
,则目标解析为通道名称。
如果你想要使用 Spring Cloud Stream,别忘了添加对 org.springframework.cloud:spring-cloud-stream
测试支持的依赖项,如下所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-test-binder</artifactId>
<scope>test</scope>
</dependency>
testImplementation('org.springframework.cloud:spring-cloud-stream-test-binder')
Adding the Runner to the Project
你可以在类路径上同时拥有 Spring Cloud Stream 和 Spring Cloud Contract Stub Runner。别忘了使用 @AutoConfigureStubRunner
为你的测试类加注释。
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[]
这将向契约输出消息中描述的目标发送一条消息。