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

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

Producer Flow

作为提供者,我们:

  1. 编写我们 API 的 RESTDocs 测试。

  2. 将 Spring Cloud Contract Stub Runner starter 添加到我们的构建中(spring-cloud-starter-contract-stub-runner),如下所示:

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. 我们设置了构建工具来打包我们的存根,如下所示:

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)

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

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

"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中使用存根进行提供者合同测试的消费者侧流程。