Provider Contract Testing with REST Docs and Stubs in Nexus or Artifactory

在此流程中,我们不使用 Spring Cloud Contract 插件生成测试和存根。我们编写 Spring RESTDocs,并自动从其中生成存根。最后,我们设置我们的构建以打包存根并将它们上传到存根存储站点,在我们的案例中是 Nexus 或 Artifactory。

In this flow, we do not use a Spring Cloud Contract plugin to generate tests and stubs. We write Spring RESTDocs, and, from them, we automatically generate stubs. Finally, we set up our builds to package the stubs and upload them to the stub storage site — in our case, Nexus or Artifactory.

Producer Flow

作为提供者,我们:

As a producer, we:

  1. Write RESTDocs tests of our API.

  2. Add Spring Cloud Contract Stub Runner starter to our build (spring-cloud-starter-contract-stub-runner), as follows:

Maven
<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>${spring-cloud.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>
Gradle
dependencies {
	testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-stub-runner'
}

dependencyManagement {
	imports {
		mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
	}
}
  1. We set up the build tool to package our stubs, as follows:

Maven
<!-- pom.xml -->
<plugins>
	<plugin>
		<groupId>org.apache.maven.plugins</groupId>
		<artifactId>maven-assembly-plugin</artifactId>
		<executions>
			<execution>
				<id>stub</id>
				<phase>prepare-package</phase>
				<goals>
					<goal>single</goal>
				</goals>
				<inherited>false</inherited>
				<configuration>
					<attach>true</attach>
					<descriptors>
						${basedir}/src/assembly/stub.xml
					</descriptors>
				</configuration>
			</execution>
		</executions>
	</plugin>
</plugins>

<!-- src/assembly/stub.xml -->
<assembly
	xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
	<id>stubs</id>
	<formats>
		<format>jar</format>
	</formats>
	<includeBaseDirectory>false</includeBaseDirectory>
	<fileSets>
		<fileSet>
			<directory>${project.build.directory}/generated-snippets/stubs</directory>
			<outputDirectory>META-INF/${project.groupId}/${project.artifactId}/${project.version}/mappings</outputDirectory>
			<includes>
				<include>**/*</include>
			</includes>
		</fileSet>
	</fileSets>
</assembly>
Gradle
task stubsJar(type: Jar) {
	classifier = "stubs"
	into("META-INF/${project.group}/${project.name}/${project.version}/mappings") {
		include('**/*.*')
		from("${project.buildDir}/generated-snippets/stubs")
	}
}
// we need the tests to pass to build the stub jar
stubsJar.dependsOn(test)
bootJar.dependsOn(stubsJar)

现在,当我们运行测试时,存根会自动发布和打包。

Now, when we run the tests, stubs are automatically published and packaged.

以下 UML 图显示了生产商流程:

The following UML diagram shows the producer flow:

"API Producer"->"API Producer": write RESTDocs tests
"API Producer"->"API Producer": add the stub runner\nstarter dependency
"API Producer"->"API Producer": setup the build tool to package\nthe generated stubs
"API Producer"->"API Producer\nbuild": run the build
"API Producer\nbuild"->"RESTDocs": generate HTTP snippets
"RESTDocs"->"Spring Cloud\nContract": generate HTTP stubs
"RESTDocs"->"Spring Cloud\nContract": (optional) generate\ncontract DSLs
"Spring Cloud\nContract"->"RESTDocs": files generated
"RESTDocs"->"API Producer\nbuild": snippets generated
"API Producer\nbuild"->"API Producer\nbuild": tests passed
"API Producer\nbuild"->"API Producer\nbuild": generate stubs jar
"API Producer\nbuild"->"Stub Storage": upload JAR with the application
"API Producer\nbuild"->"Stub Storage": upload JAR with the stubs
"Stub Storage"->"API Producer\nbuild": JARs uploaded
"API Producer\nbuild"->"API Producer": build successful

Consumer Flow

由于消费者流不受用于生成存根的工具的影响,您可以阅读Developing Your First Spring Cloud Contract-based Application来了解在Nexus或Artifactory中使用存根进行提供者合同测试的消费者侧流程。

Since the consumer flow is not affected by the tool used to generate the stubs, you can read Developing Your First Spring Cloud Contract-based Application to see the flow for consumer side of the provider contract testing with stubs in Nexus or Artifactory.