对于最新的稳定版本,请使用 spring-cloud-contract 4.3.0! |
具有外部存储库中的合同的消费者驱动合同
在此流程中,我们执行消费者驱动的合约测试。合约定义为 存储在单独的存储库中。
前提条件
要将消费者驱动的合约与外部存储库中保存的合约一起使用,您需要设置一个 git 存储库,该存储库:
-
包含每个生产者的所有合同定义。
-
可以将协定定义打包在 JAR 中。
-
对于每个合同生产者,包含一种方式(例如
pom.xml
) 安装存根 通过 Spring Cloud Contract Plugin(SCC 插件)在本地。
您还需要设置了 Spring Cloud Contract Stub Runner 的消费者代码。 有关此类项目的示例,请参阅此示例。 您还需要设置了 Spring Cloud Contract 的生产者代码以及插件。 有关此类项目的示例,请参阅此示例。 存根存储是 Nexus 或 Artifactory。
在高级别上,流量如下:
-
使用者使用来自单独存储库的协定定义。
-
使用者的工作完成后,将在使用者上创建一个包含工作代码的分支 side 中,并向保存合约定义的单独存储库发出拉取请求。
-
生产者将拉取请求接管到带有 contract 的单独存储库 定义并在本地安装带有所有协定的 JAR。
-
生产者从本地存储的 JAR 生成测试并写入缺少的 实现以使测试通过。
-
生产者的工作完成后,对保存 合同定义被合并。
-
CI 工具使用合约定义构建存储库并使用 合约定义上传到 Nexus 或 Artifactory,生产者可以合并其分支。
-
最后,消费者可以切换到在线工作,以从 远程位置,分支可以合并到主节点。
消费者流
消费者:
-
编写一个测试,将向生产者发送请求。
由于不存在服务器,测试失败。
-
克隆保存协定定义的存储库。
-
将需求设置为文件夹下的合同,并将消费者名称设置为生产者的子文件夹。
例如,对于名为
producer
和一个名为consumer
,则合约将存储在src/main/resources/contracts/producer/consumer/
) -
定义合约后,将生产者存根安装到本地存储,如以下示例所示:
$ cd src/main/resource/contracts/producer $ ./mvnw clean install
-
在消费者测试中设置 Spring Cloud Contract (SCC) Stub Runner,以:
-
从本地存储中获取生产者存根。
-
在每个使用者的存根模式下工作(这启用了使用者驱动的合约模式)。
SCC 短管运行器:
-
获取生产者存根。
-
运行包含生产者存根的内存中 HTTP 服务器存根。 现在,您的测试与 HTTP 服务器存根通信,并且您的测试通过了。
-
使用合同定义创建对存储库的拉取请求,其中包含生产者的新合同。
-
分支您的使用者代码,直到生产者团队合并其代码。
-
以下 UML 图显示了使用者流:

生产者流程
制片人:
-
接管对具有协定定义的存储库的拉取请求。你可以的 从命令行中,如下所示
$ git checkout -b the_branch_with_pull_request master git pull https://github.com/user_id/project_name.git the_branch_with_pull_request
-
安装协定定义,如下所示
$ ./mvnw clean install
-
设置插件以从 JAR 而不是从 JAR 获取合约定义
src/test/resources/contracts
如下:- 专家
-
<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> <!-- We want to use the JAR with contracts with the following coordinates --> <contractDependency> <groupId>com.example</groupId> <artifactId>beer-contracts</artifactId> </contractDependency> <!-- The JAR with contracts should be taken from Maven local --> <contractsMode>LOCAL</contractsMode> <!-- ... additional configuration --> </configuration> </plugin>
- Gradle
-
contracts { // We want to use the JAR with contracts with the following coordinates // group id `com.example`, artifact id `beer-contracts`, LATEST version and NO classifier contractDependency { stringNotation = 'com.example:beer-contracts:+:' } // The JAR with contracts should be taken from Maven local contractsMode = "LOCAL" // Additional configuration }
-
运行构建以生成测试和存根,如下所示:
- 专家
-
./mvnw clean install
- Gradle
-
./gradlew clean build
-
编写缺少的实现,使测试通过。
-
将拉取请求合并到具有协定定义的存储库,如下所示:
$ git commit -am "Finished the implementation to make the contract tests pass" $ git checkout master $ git merge --no-ff the_branch_with_pull_request $ git push origin master
CI 系统使用合约定义构建项目,并使用 Nexus 或 Artifactory 的合同定义。
-
切换到远程工作。
-
设置插件,以便不再从本地获取合约定义 存储,但来自远程位置,如下所示:
- 专家
-
<plugin> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-contract-maven-plugin</artifactId> <version>${spring-cloud-contract.version}</version> <extensions>true</extensions> <configuration> <!-- We want to use the JAR with contracts with the following coordinates --> <contractDependency> <groupId>com.example</groupId> <artifactId>beer-contracts</artifactId> </contractDependency> <!-- The JAR with contracts should be taken from a remote location --> <contractsMode>REMOTE</contractsMode> <!-- ... additional configuration --> </configuration> </plugin>
- Gradle
-
contracts { // We want to use the JAR with contracts with the following coordinates // group id `com.example`, artifact id `beer-contracts`, LATEST version and NO classifier contractDependency { stringNotation = 'com.example:beer-contracts:+:' } // The JAR with contracts should be taken from a remote location contractsMode = "REMOTE" // Additional configuration }
-
将生产者代码与新实现合并。
-
CI 系统:
-
构建项目。
-
生成测试、存根和存根 JAR。
-
将带有应用程序和存根的工件上传到 Nexus 或 Artifactory。
-
以下 UML 图显示了生产者进程:
