Files
spring-cloud-contract/docs/modules/ROOT/pages/using/provider-contract-testing-rest-docs.adoc
Marcin Grzejszczak 0159bcde09 Updated antora docs
2023-09-14 15:43:24 +02:00

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.