Sync docs from 2.0.x to gh-pages

This commit is contained in:
Marcin Grzejszczak
2017-09-12 11:53:39 +02:00
parent 0c7de60a3e
commit 98de4392f7
16 changed files with 3731 additions and 2170 deletions

View File

@@ -1,15 +1,14 @@
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>10.&nbsp;Spring Cloud Contract WireMock</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-contract.html" title="Spring Cloud Contract"><link rel="up" href="multi_spring-cloud-contract.html" title="Spring Cloud Contract"><link rel="prev" href="multi__pluggable_architecture.html" title="9.&nbsp;Pluggable architecture"><link rel="next" href="multi__migrations.html" title="11.&nbsp;Migrations"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">10.&nbsp;Spring Cloud Contract WireMock</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__pluggable_architecture.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="multi__migrations.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_spring_cloud_contract_wiremock" href="#_spring_cloud_contract_wiremock"></a>10.&nbsp;Spring Cloud Contract WireMock</h1></div></div></div><p>Modules giving you the possibility to use
<a class="link" href="http://wiremock.org" target="_top">WireMock</a> in a Spring Boot application. Check out the
<title>10.&nbsp;Spring Cloud Contract WireMock</title><link rel="stylesheet" type="text/css" href="css/manual-multipage.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="multi_spring-cloud-contract.html" title="Spring Cloud Contract"><link rel="up" href="multi_spring-cloud-contract.html" title="Spring Cloud Contract"><link rel="prev" href="multi__using_the_pluggable_architecture.html" title="9.&nbsp;Using the Pluggable Architecture"><link rel="next" href="multi__migrations.html" title="11.&nbsp;Migrations"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">10.&nbsp;Spring Cloud Contract WireMock</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__using_the_pluggable_architecture.html">Prev</a>&nbsp;</td><th width="60%" align="center">&nbsp;</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="multi__migrations.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_spring_cloud_contract_wiremock" href="#_spring_cloud_contract_wiremock"></a>10.&nbsp;Spring Cloud Contract WireMock</h1></div></div></div><p>The Spring Cloud Contract WireMock modules let you use <a class="link" href="http://wiremock.org" target="_top">WireMock</a> in a
Spring Boot application. Check out the
<a class="link" href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples" target="_top">samples</a>
for more details.</p><p>If you have a Spring Boot application that uses Tomcat as an embedded
server, for example (the default with <code class="literal">spring-boot-starter-web</code>), then
you can simply add <code class="literal">spring-cloud-contract-wiremock</code> to your classpath
and add <code class="literal">@AutoConfigureWireMock</code> in order to be able to use Wiremock
in your tests. Wiremock runs as a stub server and you can register
stub behaviour using a Java API or via static JSON declarations as
part of your test. Here&#8217;s a simple example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
for more details.</p><p>If you have a Spring Boot application that uses Tomcat as an embedded server (which is
the default with <code class="literal">spring-boot-starter-web</code>), you can add
<code class="literal">spring-cloud-contract-wiremock</code> to your classpath and add <code class="literal">@AutoConfigureWireMock</code> in
order to be able to use Wiremock in your tests. Wiremock runs as a stub server and you
can register stub behavior using a Java API or via static JSON declarations as part of
your test. The following code shows an example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)</span></em>
<em><span class="hl-annotation" style="color: gray">@AutoConfigureWireMock(port = 0)</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> WiremockForDocsTests {
@@ -26,12 +25,16 @@ part of your test. Here&#8217;s a simple example:</p><pre class="programlisting"
assertThat(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.service.go()).isEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World!"</span>);
}
}</pre><p>To start the stub server on a different port use <code class="literal">@AutoConfigureWireMock(port=9999)</code> (for example), and for a random port use the value 0. The stub server port will be bindable in the test application context as "wiremock.server.port". Using <code class="literal">@AutoConfigureWireMock</code> adds a bean of type <code class="literal">WiremockConfiguration</code> to your test application context, where it will be cached in between methods and classes having the same context, just like for normal Spring integration tests.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_stubs_automatically" href="#_registering_stubs_automatically"></a>10.1&nbsp;Registering Stubs Automatically</h2></div></div></div><p>If you use <code class="literal">@AutoConfigureWireMock</code> then it will register WireMock
JSON stubs from the file system or classpath, by default from
<code class="literal">file:src/test/resources/mappings</code>. You can customize the locations
using the <code class="literal">stubs</code> attribute in the annotation, which can be a resource
pattern (ant-style) or a directory, in which case <code class="literal"><span class="strong"><strong>*/</strong></span>.json</code> is
appended. Example:</p><pre class="screen">@RunWith(SpringRunner.class)
}</pre><p>To start the stub server on a different port use (for example),
<code class="literal">@AutoConfigureWireMock(port=9999)</code>. For a random port, use a value of <code class="literal">0</code>. The stub
server port can be bound in the test application context with the "wiremock.server.port"
property. Using <code class="literal">@AutoConfigureWireMock</code> adds a bean of type <code class="literal">WiremockConfiguration</code> to
your test application context, where it will be cached in between methods and classes
having the same context, the same as for Spring integration tests.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_registering_stubs_automatically" href="#_registering_stubs_automatically"></a>10.1&nbsp;Registering Stubs Automatically</h2></div></div></div><p>If you use <code class="literal">@AutoConfigureWireMock</code>, it registers WireMock JSON stubs from the file
system or classpath (by default, from <code class="literal">file:src/test/resources/mappings</code>). You can
customize the locations using the <code class="literal">stubs</code> attribute in the annotation, which can be an
Ant-style resource pattern or a directory. In the case of a directory, <code class="literal"><span class="strong"><strong>*/</strong></span>.json</code> is
appended. The following code shows an example:</p><pre class="screen">@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWireMock(stubs="classpath:/stubs")
public class WiremockImportApplicationTests {
@@ -44,25 +47,22 @@ public class WiremockImportApplicationTests {
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Actually WireMock always loads mappings from
<code class="literal">src/test/resources/mappings</code> <span class="strong"><strong>as well as</strong></span> the custom locations in the
stubs attribute. To change this behaviour you have to also specify a
files root as described next.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_files_to_specify_the_stub_bodies" href="#_using_files_to_specify_the_stub_bodies"></a>10.2&nbsp;Using Files to Specify the Stub Bodies</h2></div></div></div><p>WireMock can read response bodies from files on the classpath or file
system. In that case you will see in the JSON DSL that the response
has a "bodyFileName" instead of a (literal) "body". The files are
resolved relative to a root directory <code class="literal">src/test/resources/__files</code> by
default. To customize this location you can set the <code class="literal">files</code> attribute
in the <code class="literal">@AutoConfigureWireMock</code> annotation to the location of the
parent directory (i.e. the place <code class="literal">__files</code> is a
subdirectory). You can use Spring resource notation to refer to
<code class="literal">file:&#8230;&#8203;</code> or <code class="literal">classpath:&#8230;&#8203;</code> locations (but generic URLs are not
supported). A list of values can be given and WireMock will resolve
the first file that exists when it needs to find a response body.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>when you configure the <code class="literal">files</code> root, then it affects the
automatic loading of stubs as well (they come from the root location
in a subdirectory called "mappings"). The value of <code class="literal">files</code> has no
effect on the stubs loaded explicitly from the <code class="literal">stubs</code> attribute.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_alternative_using_junit_rules" href="#_alternative_using_junit_rules"></a>10.3&nbsp;Alternative: Using JUnit Rules</h2></div></div></div><p>For a more conventional WireMock experience, using JUnit <code class="literal">@Rules</code> to
start and stop the server, just use the <code class="literal">WireMockSpring</code> convenience
class to obtain an <code class="literal">Options</code> instance:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
}</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>Actually, WireMock always loads mappings from <code class="literal">src/test/resources/mappings</code> <span class="strong"><strong>as
well as</strong></span> the custom locations in the stubs attribute. To change this behavior, you can
also specify a files root as described in the next section of this document.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_using_files_to_specify_the_stub_bodies" href="#_using_files_to_specify_the_stub_bodies"></a>10.2&nbsp;Using Files to Specify the Stub Bodies</h2></div></div></div><p>WireMock can read response bodies from files on the classpath or the file system. In that
case, you can see in the JSON DSL that the response has a <code class="literal">bodyFileName</code> instead of a
(literal) <code class="literal">body</code>. The files are resolved relative to a root directory (by default,
<code class="literal">src/test/resources/__files</code>). To customize this location you can set the <code class="literal">files</code>
attribute in the <code class="literal">@AutoConfigureWireMock</code> annotation to the location of the parent
directory (in other words, <code class="literal">__files</code> is a subdirectory). You can use Spring resource
notation to refer to <code class="literal">file:&#8230;&#8203;</code> or <code class="literal">classpath:&#8230;&#8203;</code> locations. Generic URLs are not
supported. A list of values can be given, in which case WireMock resolves the first file
that exists when it needs to find a response body.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>When you configure the <code class="literal">files</code> root, it also affects the
automatic loading of stubs, because they come from the root location
in a subdirectory called "mappings". The value of <code class="literal">files</code> has no
effect on the stubs loaded explicitly from the <code class="literal">stubs</code> attribute.</p></td></tr></table></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_alternative_using_junit_rules" href="#_alternative_using_junit_rules"></a>10.3&nbsp;Alternative: Using JUnit Rules</h2></div></div></div><p>For a more conventional WireMock experience, you can use JUnit <code class="literal">@Rules</code> to start and stop
the server. To do so, use the <code class="literal">WireMockSpring</code> convenience class to obtain an <code class="literal">Options</code>
instance, as shown in the followin example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> WiremockForDocsClassRuleTests {
@@ -85,18 +85,21 @@ class to obtain an <code class="literal">Options</code> instance:</p><pre class=
assertThat(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.service.go()).isEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World!"</span>);
}
}</pre><p>The use <code class="literal">@ClassRule</code> means that the server will shut down after all the methods in this class.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_relaxed_ssl_validation_for_rest_template" href="#_relaxed_ssl_validation_for_rest_template"></a>10.4&nbsp;Relaxed SSL Validation for Rest Template</h2></div></div></div><p>WireMock allows you to stub a "secure" server with an "https" URL protocol. If your application wants to
contact that stub server in an integration test, then it will find that the SSL certificates are not
valid (it&#8217;s the usual problem with self-installed certificates). The best option is often to just
re-configure the client to use "http", but if that&#8217;s not open to you then you can ask Spring to configure
an HTTP client that ignores SSL validation errors (just for tests).</p><p>To make this work with minimum fuss you need to be using the Spring Boot <code class="literal">RestTemplateBuilder</code> in your app,
e.g.</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
}</pre><p>The <code class="literal">@ClassRule</code> means that the server shuts down after all the methods in this class
have been run.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_relaxed_ssl_validation_for_rest_template" href="#_relaxed_ssl_validation_for_rest_template"></a>10.4&nbsp;Relaxed SSL Validation for Rest Template</h2></div></div></div><p>WireMock lets you stub a "secure" server with an "https" URL protocol. If your
application wants to contact that stub server in an integration test, it will find that
the SSL certificates are not valid (the usual problem with self-installed certificates).
The best option is often to re-configure the client to use "http". If that&#8217;s not an
option, you can ask Spring to configure an HTTP client that ignores SSL validation errors
(do so only for tests, of course).</p><p>To make this work with minimum fuss, you need to be using the Spring Boot
<code class="literal">RestTemplateBuilder</code> in your app, as shown in the following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Bean</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> RestTemplate restTemplate(RestTemplateBuilder builder) {
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> builder.build();
}</pre><p>This is because the builder is passed through callbacks to initalize it, so the SSL validation can be set up
in the client at that point. This will happen automatically in your test if you are using the
<code class="literal">@AutoConfigureWireMock</code> annotation (or the stub runner). If you are using the JUnit <code class="literal">@Rule</code> approach you need
to add the <code class="literal">@AutoConfigureHttpClient</code> annotation as well:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
}</pre><p>You need <code class="literal">RestTemplateBuilder</code> because the builder is passed through callbacks to
initialize it, so the SSL validation can be set up in the client at that point. This
happens automatically in your test if you are using the <code class="literal">@AutoConfigureWireMock</code>
annotation or the stub runner. If you use the JUnit <code class="literal">@Rule</code> approach, you need to add the
<code class="literal">@AutoConfigureHttpClient</code> annotation as well, as shown in the following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest("app.baseUrl=https://localhost:6443")</span></em>
<em><span class="hl-annotation" style="color: gray">@AutoConfigureHttpClient</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> WiremockHttpsServerApplicationTests {
@@ -105,11 +108,12 @@ to add the <code class="literal">@AutoConfigureHttpClient</code> annotation as w
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">static</span> WireMockClassRule wiremock = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> WireMockClassRule(
WireMockSpring.options().httpsPort(<span class="hl-number">6443</span>));
...
}</pre><p>If you are using <code class="literal">spring-boot-starter-test</code> then you will have the Apache HTTP client on the classpath and it will
be selected by the <code class="literal">RestTemplateBuilder</code> and configured to ignore SSL errors. If you are using the default <code class="literal">java.net</code>
client you don&#8217;t need the annotation (but it won&#8217;t do any harm). There is no support currently for other clients, but
it may be added in future releases.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_wiremock_and_spring_mvc_mocks" href="#_wiremock_and_spring_mvc_mocks"></a>10.5&nbsp;WireMock and Spring MVC Mocks</h2></div></div></div><p>Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into a
Spring <code class="literal">MockRestServiceServer</code>. Here&#8217;s an example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
}</pre><p>If you are using <code class="literal">spring-boot-starter-test</code>, you have the Apache HTTP client on the
classpath and it is selected by the <code class="literal">RestTemplateBuilder</code> and configured to ignore SSL
errors. If you use the default <code class="literal">java.net</code> client, you do not need the annotation (but it
won&#8217;t do any harm). There is no support currently for other clients, but it may be added
in future releases.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_wiremock_and_spring_mvc_mocks" href="#_wiremock_and_spring_mvc_mocks"></a>10.5&nbsp;WireMock and Spring MVC Mocks</h2></div></div></div><p>Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into
a Spring <code class="literal">MockRestServiceServer</code>. The following code shows an example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest(webEnvironment = WebEnvironment.NONE)</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> WiremockForDocsMockServerApplicationTests {
@@ -129,26 +133,23 @@ Spring <code class="literal">MockRestServiceServer</code>. Here&#8217;s an examp
assertThat(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.service.go()).isEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World"</span>);
server.verify();
}
}</pre><p>The <code class="literal">baseUrl</code> is prepended to all mock calls, and the <code class="literal">stubs()</code>
method takes a stub path resource pattern as an argument. So in this
example the stub defined at <code class="literal">/stubs/resource.json</code> is loaded into the
mock server, so if the <code class="literal">RestTemplate</code> is asked to visit
<code class="literal"><a class="link" href="http://example.org/" target="_top">http://example.org/</a></code> it will get the responses as declared
there. More than one stub pattern can be specified, and each one can
be a directory (for a recursive list of all ".json"), or a fixed
filename (like in the example above) or an ant-style pattern. The JSON
format is the normal WireMock format which you can read about in the
WireMock website.</p><p>Currently we support Tomcat, Jetty and Undertow as Spring Boot
embedded servers, and Wiremock itself has "native" support for a
particular version of Jetty (currently 9.2). To use the native Jetty
you need to add the native wiremock dependencies and exclude the
Spring Boot container if there is one.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_generating_stubs_using_restdocs" href="#_generating_stubs_using_restdocs"></a>10.6&nbsp;Generating Stubs using RestDocs</h2></div></div></div><p><a class="link" href="https://projects.spring.io/spring-restdocs" target="_top">Spring RestDocs</a> can be
used to generate documentation (e.g. in asciidoctor format) for an
HTTP API with Spring MockMvc or Rest Assured. At the same time as you
generate documentation for your API, you can also generate WireMock
stubs, by using Spring Cloud Contract WireMock. Just write your normal
RestDocs test cases and use <code class="literal">@AutoConfigureRestDocs</code> to have stubs
automatically in the restdocs output directory. For example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
}</pre><p>The <code class="literal">baseUrl</code> value is prepended to all mock calls, and the <code class="literal">stubs()</code> method takes a stub
path resource pattern as an argument. In the preceding example, the stub defined at
<code class="literal">/stubs/resource.json</code> is loaded into the mock server. If the <code class="literal">RestTemplate</code> is asked to
visit <code class="literal"><a class="link" href="http://example.org/" target="_top">http://example.org/</a></code>, it gets the responses as being declared at that URL. More
than one stub pattern can be specified, and each one can be a directory (for a recursive
list of all ".json"), a fixed filename (as in the example above), or an Ant-style
pattern. The JSON format is the normal WireMock format, which you can read about in the
<a class="link" href="http://wiremock.org/docs/stubbing/" target="_top">WireMock website</a>.</p><p>Currently, the Spring Cloud Contract Verifier supports Tomcat, Jetty, and Undertow as
Spring Boot embedded servers, and Wiremock itself has "native" support for a particular
version of Jetty (currently 9.2). To use the native Jetty, you need to add the native
Wiremock dependencies and exclude the Spring Boot container (if there is one).</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_generating_stubs_using_rest_docs" href="#_generating_stubs_using_rest_docs"></a>10.6&nbsp;Generating Stubs using REST Docs</h2></div></div></div><p><a class="link" href="https://projects.spring.io/spring-restdocs" target="_top">Spring REST Docs</a> can be used to generate
documentation (for example in Asciidoctor format) for an HTTP API with Spring MockMvc or
Rest Assured. At the same time that you generate documentation for your API, you can also
generate WireMock stubs by using Spring Cloud Contract WireMock. To do so, write your
normal REST Docs test cases and use <code class="literal">@AutoConfigureRestDocs</code> to have stubs be
automatically generated in the REST Docs output directory. The following code shows an
example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest</span></em>
<em><span class="hl-annotation" style="color: gray">@AutoConfigureRestDocs(outputDir = "target/snippets")</span></em>
<em><span class="hl-annotation" style="color: gray">@AutoConfigureMockMvc</span></em>
@@ -163,16 +164,12 @@ automatically in the restdocs output directory. For example:</p><pre class="prog
.andExpect(content().string(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World"</span>))
.andDo(document(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"resource"</span>));
}
}</pre><p>From this test will be generated a WireMock stub at
"target/snippets/stubs/resource.json". It matches all GET requests to
the "/resource" path.</p><p>Without any additional configuration this will create a stub with a
request matcher for the HTTP method and all headers except "host" and
"content-length". To match the request more precisely, for example to
match the body of a POST or PUT, we need to explicitly create a
request matcher. This will do two things: 1) create a stub that only
matches the way you specify, 2) assert that the request in the test
case also matches the same conditions.</p><p>The main entry point for this is <code class="literal">WireMockRestDocs.verify()</code> which can
be used as a substitute for the <code class="literal">document()</code> convenience method. For
}</pre><p>This test generates a WireMock stub at "target/snippets/stubs/resource.json". It matches
all GET requests to the "/resource" path.</p><p>Without any additional configuration, this tests creates a stub with a request matcher
for the HTTP method and all headers except "host" and "content-length". To match the
request more precisely (for example, to match the body of a POST or PUT), we need to
explicitly create a request matcher. Doing so has two effects:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Creating a stub that matches only in the way you specify.</li><li class="listitem">Asserting that the request in the test case also matches the same conditions.</li></ul></div><p>The main entry point for this feature is <code class="literal">WireMockRestDocs.verify()</code>, which can be used
as a substitute for the <code class="literal">document()</code> convenience method, as shown in the following
example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@RunWith(SpringRunner.class)</span></em>
<em><span class="hl-annotation" style="color: gray">@SpringBootTest</span></em>
<em><span class="hl-annotation" style="color: gray">@AutoConfigureRestDocs(outputDir = "target/snippets")</span></em>
@@ -190,13 +187,12 @@ example:</p><pre class="programlisting"><em><span class="hl-annotation" style="c
.andDo(verify().jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.id"</span>)
.stub(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"resource"</span>));
}
}</pre><p>So this contract is saying: any valid POST with an "id" field will get
back an the same response as in this test. You can chain together
calls to <code class="literal">.jsonPath()</code> to add additional matchers. The
<a class="link" href="https://github.com/jayway/JsonPath" target="_top">JayWay documentation</a> can help you
to get up to speed with JSON Path if it is unfamiliar to you.</p><p>Instead of the <code class="literal">jsonPath</code> and <code class="literal">contentType</code> convenience methods, you
can also use the WireMock APIs to verify the request matches the
created stub. Example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Test</span></em>
}</pre><p>This contract specifies that any valid POST with an "id" field receives the response
defined in this test. You can chain together calls to <code class="literal">.jsonPath()</code> to add additional
matchers. If JSON Path is unfamiliar, The <a class="link" href="https://github.com/jayway/JsonPath" target="_top">JayWay
documentation</a> can help you get up to speed.</p><p>Instead of the <code class="literal">jsonPath</code> and <code class="literal">contentType</code> convenience methods, you can also use the
WireMock APIs to verify that the request matches the created stub, as shown in the
following example:</p><pre class="programlisting"><em><span class="hl-annotation" style="color: gray">@Test</span></em>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">public</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">void</span> contextLoads() <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">throws</span> Exception {
mockMvc.perform(post(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span>)
.content(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\"id\":\"123456\",\"message\":\"Hello World\"}"</span>))
@@ -206,10 +202,9 @@ created stub. Example:</p><pre class="programlisting"><em><span class="hl-annota
urlPathEquals(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span>))
.withRequestBody(matchingJsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.id"</span>))
.stub(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"post-resource"</span>));
}</pre><p>The WireMock API is rich - you can match headers, query parameters,
and request body by regex as well as by json path - so this can useful
to create stubs with a wider range of parameters. The above example
will generate a stub something like this:</p><p><b>post-resource.json.&nbsp;</b>
}</pre><p>The WireMock API is rich. You can match headers, query parameters, and request body by
regex as well as by JSON path. These features can be used to create stubs with a wider
range of parameters. The above example generates a stub resembling the following example:</p><p><b>post-resource.json.&nbsp;</b>
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"request"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"url"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
@@ -227,20 +222,21 @@ will generate a stub something like this:</p><p><b>post-resource.json.&nbsp;</b>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span></pre><p>
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You can use either the <code class="literal">wiremock()</code> method or the <code class="literal">jsonPath()</code>
and <code class="literal">contentType()</code> methods to create request matchers, but not both.</p></td></tr></table></div><p>On the consumer side, you can make the <code class="literal">resource.json</code> generated above
available on the classpath (by <a class="link" href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_publishing_stubs_as_jars" target="_top">publishing stubs as JARs</a> for example).
After that, you can create a stub using WireMock in a
number of different ways, including as described above using
<code class="literal">@AutoConfigureWireMock(stubs="classpath:resource.json")</code>.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_generating_contracts_using_restdocs" href="#_generating_contracts_using_restdocs"></a>10.7&nbsp;Generating Contracts using RestDocs</h2></div></div></div><p>Another thing that can be generated with Spring RestDocs is the Spring Cloud
Contract DSL file and documentation. If you combine that with Spring Cloud
WireMock then you&#8217;re getting both the contracts and stubs.</p><p>Why would you want to use this feature? Some people in the community asked questions
about situation in which they would like to move to DSL based contract definition
but they already have a lot of Spring MVC tests. Using this feature allows you to generate
the contract files that you can later modify and move to proper folders so that the
plugin picks them up.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>You might wonder why this functionality is in the WireMock module.
Come to think of it, it does make sense since it makes little sense to generate
only contracts and not generate the stubs. That&#8217;s why we suggest to do both.</p></td></tr></table></div><p>Let&#8217;s imagine the following test:</p><pre class="programlisting"> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.mockMvc.perform(post(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/foo"</span>)
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>You can use either the <code class="literal">wiremock()</code> method or the <code class="literal">jsonPath()</code> and <code class="literal">contentType()</code>
methods to create request matchers, but you can&#8217;t use both approaches.</p></td></tr></table></div><p>On the consumer side, you can make the <code class="literal">resource.json</code> generated earlier in this section
available on the classpath (by
<a class="link" href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_publishing_stubs_as_jars" target="_top">publishing
stubs as JARs</a>, for example). After that, you can create a stub using WireMock in a
number of different ways, including by using
<code class="literal">@AutoConfigureWireMock(stubs="classpath:resource.json")</code>, as described earlier in this
document.</p></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_generating_contracts_by_using_rest_docs" href="#_generating_contracts_by_using_rest_docs"></a>10.7&nbsp;Generating Contracts by Using REST Docs</h2></div></div></div><p>You can also generate Spring Cloud Contract DSL files and documentation with Spring REST
Docs. If you do so in combination with Spring Cloud WireMock, you get both the contracts
and the stubs.</p><p>Why would you want to use this feature? Some people in the community asked questions
about a situation in which they would like to move to DSL-based contract definition,
but they already have a lot of Spring MVC tests. Using this feature lets you generate
the contract files that you can later modify and move to folders (defined in your
configuration) so that the plugin finds them.</p><div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Tip"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="images/tip.png"></td><th align="left">Tip</th></tr><tr><td align="left" valign="top"><p>You might wonder why this functionality is in the WireMock module. The functionality
is there because it makes sense to generate both the contracts and the stubs.</p></td></tr></table></div><p>Consider the following test:</p><pre class="programlisting"> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.mockMvc.perform(post(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/foo"</span>)
.accept(MediaType.APPLICATION_PDF)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
@@ -253,8 +249,8 @@ only contracts and not generate the stubs. That&#8217;s why we suggest to do bot
.contentType(MediaType.valueOf(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/json"</span>))
.stub(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"shouldGrantABeerIfOldEnough"</span>))
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// then Contract DSL documentation</span>
.andDo(document(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"index"</span>, SpringCloudContractRestDocs.dslContract()));</pre><p>This will lead in the creation of the stub as presented in the previous
section, contract will get generated and a documentation file too.</p><p>The contract will be called <code class="literal">index.groovy</code> and look more like this.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.Contract
.andDo(document(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"index"</span>, SpringCloudContractRestDocs.dslContract()));</pre><p>The preceding test creates the stub presented in the previous section, generating both
the contract and a documentation file.</p><p>The contract is called <code class="literal">index.groovy</code> and might look like the following example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
@@ -281,5 +277,5 @@ Contract.make {
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$[?(@.foo &gt;= 20)]'</span>, byType())
}
}
}</pre><p>the generated document (example for Asciidoc) will contain a formatted contract
(the location of this file would be <code class="literal">index/dsl-contract.adoc</code>).</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__pluggable_architecture.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="multi__migrations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.&nbsp;Pluggable architecture&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-contract.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;11.&nbsp;Migrations</td></tr></table></div></body></html>
}</pre><p>The generated document (formatted in Asciidoc in this case) contains a formatted
contract. The location of this file would be <code class="literal">index/dsl-contract.adoc</code>.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__using_the_pluggable_architecture.html">Prev</a>&nbsp;</td><td width="20%" align="center">&nbsp;</td><td width="40%" align="right">&nbsp;<a accesskey="n" href="multi__migrations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.&nbsp;Using the Pluggable Architecture&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-contract.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;11.&nbsp;Migrations</td></tr></table></div></body></html>