[[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"] ---- org.springframework.cloud spring-cloud-starter-contract-stub-runner test org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import ---- 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"] ---- org.apache.maven.plugins maven-assembly-plugin stub prepare-package single false true ${basedir}/src/assembly/stub.xml stubs jar false ${project.build.directory}/generated-snippets/stubs META-INF/${project.groupId}/${project.artifactId}/${project.version}/mappings **/* ---- 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.