Provider Contract Testing with Stubs in Git

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

In this flow, we perform the provider contract testing (the producer has no knowledge of how consumers use their API). The stubs are uploaded to a separate repository (they are not uploaded to Artifactory or Nexus).

Prerequisites

在 git 中使用存根测试提供程序合同之前,您必须提供包含每个生产者的所有存根的 git 存储库。有关此类项目的示例,请参阅 {samples_code}/contract_git[此示例 ]或 {samples_code}/contract_git[此示例]。将存根推送到此处会使存储库具有以下结构:

Before testing provider contracts with stubs in git, you must provide a git repository that contains all the stubs for each producer. For an example of such a project, see {samples_code}/contract_git[this samples ] or {samples_code}/contract_git[this sample]. As a result of pushing stubs there, the repository has the following structure:

$ 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 的消费者代码。有关此类项目的示例,请参阅 {samples_code}/consumer[此示例]并搜索 `BeerControllerGitTest`测试。您还必须提供具有 Spring Cloud Contract 设置(以及插件)的生产者代码。有关此类项目的示例,请参阅 {samples_code}/producer_with_empty_git[此示例]。

You must also provide consumer code that has Spring Cloud Contract Stub Runner set up. For an example of such a project, see {samples_code}/consumer[this sample] and search for a BeerControllerGitTest test. You must also provide producer code that has Spring Cloud Contract set up, together with a plugin. For an example of such a project, see {samples_code}/producer_with_empty_git[this sample].

The Flow

流程看起来完全像 Developing Your First Spring Cloud Contract based application中显示的那样,但 `Stub Storage`实现是 git 存储库。

The flow looks exactly as the one presented in Developing Your First Spring Cloud Contract based application, but the Stub Storage implementation is a git repository.

您可以在文档的 How To page中阅读更多有关设置 git 存储库以及设置消费者端和生产者端的信息。

You can read more about setting up a git repository and setting consumer and producer side in the How To page of the documentation.

Consumer setup

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

In order to fetch the stubs from a git repository instead of Nexus or Artifactory, you need to use the git protocol in the URL of the repositoryRoot property in Stub Runner. The following example shows how to set it up:

===Annotation

=== Annotation::

+

@AutoConfigureStubRunner(
stubsMode = StubRunnerProperties.StubsMode.REMOTE,
		repositoryRoot = "git://git@github.com: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://git@github.com: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://git@github.com:spring-cloud-samples/spring-cloud-contract-nodejs-contracts-git.git")
			.stubsMode(StubRunnerProperties.StubsMode.REMOTE);

===

Setting up the Producer

要将存根推送到 Git 存储库,而不是 Nexus 或 Artifactory,则需要在插件设置的 URL 中使用 git 协议。此外,你还需要明确告知插件在构建过程的末尾推送存根。以下示例显示如何在 Maven 和 Gradle 中执行此操作:

To push the stubs to a git repository instead of Nexus or Artifactory, you need to use the git protocol in the URL of the plugin setup. Also you need to explicitly tell the plugin to push the stubs at the end of the build process. The following examples show how to do so in both Maven and Gradle:

===Maven

=== 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://git@github.com: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://git@github.com: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")

===

您可以在文档的 How To section中阅读更多有关设置 git 存储库的信息。

You can read more about setting up a git repository in the How To section of the documentation.