156 lines
4.8 KiB
Plaintext
156 lines
4.8 KiB
Plaintext
[[flows-provider-rest-docs]]
|
|
= Provider Contract Testing with REST Docs and Stubs in Nexus or Artifactory
|
|
|
|
include::partial$_attributes.adoc[]
|
|
|
|
In this flow, we do not use a Spring Cloud Contract plugin to generate tests and stubs. We write https://spring.io/projects/spring-restdocs[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.
|
|
|
|
[[flows-provider-rest-docs-producer]]
|
|
== Producer Flow
|
|
|
|
As a producer, we:
|
|
|
|
. Write RESTDocs tests of our API.
|
|
. Add Spring Cloud Contract Stub Runner starter to our build (`spring-cloud-starter-contract-stub-runner`), as follows:
|
|
+
|
|
[tabs]
|
|
======
|
|
Maven::
|
|
+
|
|
[source,xml,indent=0,role="primary"]
|
|
----
|
|
<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::
|
|
+
|
|
[source,groovy,indent=0,role="secondary"]
|
|
----
|
|
dependencies {
|
|
testImplementation 'org.springframework.cloud:spring-cloud-starter-contract-stub-runner'
|
|
}
|
|
|
|
dependencyManagement {
|
|
imports {
|
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
|
|
}
|
|
}
|
|
----
|
|
======
|
|
. We set up the build tool to package our stubs, as follows:
|
|
+
|
|
[tabs]
|
|
======
|
|
Maven::
|
|
+
|
|
[source,xml,indent=0,role="primary"]
|
|
----
|
|
<!-- 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::
|
|
+
|
|
[source,groovy,indent=0,role="secondary"]
|
|
----
|
|
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.
|
|
|
|
The following UML diagram shows the producer flow:
|
|
|
|
[plantuml, flows-provider-rest-docs-producer, png]
|
|
----
|
|
"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
|
|
----
|
|
|
|
[[flows-provider-rest-docs-consumer]]
|
|
== Consumer Flow
|
|
|
|
Since the consumer flow is not affected by the tool used to generate the stubs, you can read xref:getting-started/first-application.adoc#getting-started-first-application-consumer[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.
|