使用 Git 中的存根进行提供者契约测试

在此流程中,我们执行提供者契约测试(生产者不知道消费者如何使用其 API)。存根被上传到单独的仓库(而不是上传到 Artifactory 或 Nexus)。

先决条件

在使用 git 中的存根测试提供者契约之前,您必须提供一个包含每个生产者所有存根的 git 仓库。有关此类项目的示例,请参见此示例此示例。将存根推送到该仓库后,仓库结构如下:

$ tree .
└── META-INF
   └── folder.with.group.id.as.its.name
       └── folder-with-artifact-id
           └── folder-with-version
               ├── contractA.groovy
               ├── contractB.yml
               └── contractC.groovy

您还必须提供设置了 Spring Cloud Contract Stub Runner 的消费者代码。有关此类项目的示例,请参见此示例并搜索 BeerControllerGitTest 测试。您还必须提供设置了 Spring Cloud Contract 并带有插件的生产者代码。有关此类项目的示例,请参见此示例

流程

此流程与开发您的第一个基于 Spring Cloud Contract 的应用中介绍的流程完全相同,但 Stub Storage 实现是一个 git 仓库。

您可以在文档的操作指南页面中了解更多关于设置 git 仓库以及设置消费者和生产者端的信息。

消费者端设置

为了从 git 仓库而不是 Nexus 或 Artifactory 获取存根,您需要在 Stub Runner 的 repositoryRoot 属性的 URL 中使用 git 协议。以下示例展示了如何进行设置:

注解
@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
		repositoryRoot = "git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git",
		ids = "com.example:artifact-id:0.0.1")
JUnit 4 Rule
@Rule
	public StubRunnerRule rule = new StubRunnerRule()
			.downloadStub("com.example","artifact-id", "0.0.1")
			.repoRoot("git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);
JUnit 5 Extension
@RegisterExtension
	public StubRunnerExtension stubRunnerExtension = new StubRunnerExtension()
			.downloadStub("com.example","artifact-id", "0.0.1")
			.repoRoot("git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);

生产者端设置

要将存根推送到 git 仓库而不是 Nexus 或 Artifactory,您需要在插件设置的 URL 中使用 git 协议。此外,您还需要明确告诉插件在构建过程结束时推送存根。以下示例展示了如何在 Maven 和 Gradle 中完成此操作:

Maven
<plugin>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    <version>${spring-cloud-contract.version}</version>
    <extensions>true</extensions>
    <configuration>
        <!-- Base class mappings etc. -->

        <!-- We want to pick contracts from a Git repository -->
        <contractsRepositoryUrl>git://git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git</contractsRepositoryUrl>

        <!-- We reuse the contract dependency section to set up the path
        to the folder that contains the contract definitions. In our case the
        path will be /groupId/artifactId/version/contracts -->
        <contractDependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>${project.artifactId}</artifactId>
            <version>${project.version}</version>
        </contractDependency>

        <!-- The contracts mode can't be classpath -->
        <contractsMode>REMOTE</contractsMode>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <!-- By default we will not push the stubs back to SCM,
                you have to explicitly add it as a goal -->
                <goal>pushStubsToScm</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Gradle
contracts {
	// We want to pick contracts from a Git repository
	contractDependency {
		stringNotation = "${project.group}:${project.name}:${project.version}"
	}
	/*
	We reuse the contract dependency section to set up the path
	to the folder that contains the contract definitions. In our case the
	path will be /groupId/artifactId/version/contracts
	 */
	contractRepository {
		repositoryUrl = "git://git://[email protected]:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git"
	}
	// The mode can't be classpath
	contractsMode = "REMOTE"
	// Base class mappings etc.
}

/*
In this scenario we want to publish stubs to SCM whenever
the `publish` task is run
*/
publish.dependsOn("publishStubsToScm")

您可以在文档的操作指南章节中了解更多关于设置 git 仓库的信息。