Files
spring-cloud-contract/reference/html/spring-cloud-wiremock.html
2019-07-31 00:23:56 +00:00

700 lines
27 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.7.1">
<title>Spring Cloud Contract WireMock</title>
<link rel="stylesheet" href="css/spring.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.hidden {
display: none;
}
.switch {
border-width: 1px 1px 0 1px;
border-style: solid;
border-color: #7a2518;
display: inline-block;
}
.switch--item {
padding: 10px;
background-color: #ffffff;
color: #7a2518;
display: inline-block;
cursor: pointer;
}
.switch--item:not(:first-child) {
border-width: 0 0 0 1px;
border-style: solid;
border-color: #7a2518;
}
.switch--item.selected {
background-color: #7a2519;
color: #ffffff;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
<script type="text/javascript">
function addBlockSwitches() {
$('.primary').each(function() {
primary = $(this);
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
primary.children('.title').remove();
});
$('.secondary').each(function(idx, node) {
secondary = $(node);
primary = findPrimary(secondary);
switchItem = createSwitchItem(secondary, primary.children('.switch'));
switchItem.content.addClass('hidden');
findPrimary(secondary).append(switchItem.content);
secondary.remove();
});
}
function createBlockSwitch(primary) {
blockSwitch = $('<div class="switch"></div>');
primary.prepend(blockSwitch);
return blockSwitch;
}
function findPrimary(secondary) {
candidate = secondary.prev();
while (!candidate.is('.primary')) {
candidate = candidate.prev();
}
return candidate;
}
function createSwitchItem(block, blockSwitch) {
blockName = block.children('.title').text();
content = block.children('.content').first().append(block.next('.colist'));
item = $('<div class="switch--item">' + blockName + '</div>');
item.on('click', '', content, function(e) {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
e.data.siblings('.content').addClass('hidden');
e.data.removeClass('hidden');
});
blockSwitch.append(item);
return {'item': item, 'content': content};
}
$(addBlockSwitches);
</script>
</head>
<body class="book toc2 toc-left">
<div id="header">
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_spring_cloud_contract_wiremock">Spring Cloud Contract WireMock</a>
<ul class="sectlevel2">
<li><a href="#_registering_stubs_automatically">Registering Stubs Automatically</a></li>
<li><a href="#_using_files_to_specify_the_stub_bodies">Using Files to Specify the Stub Bodies</a></li>
<li><a href="#_alternative_using_junit_rules">Alternative: Using JUnit Rules</a></li>
<li><a href="#_relaxed_ssl_validation_for_rest_template">Relaxed SSL Validation for Rest Template</a></li>
<li><a href="#_wiremock_and_spring_mvc_mocks">WireMock and Spring MVC Mocks</a></li>
<li><a href="#_customization_of_wiremock_configuration">Customization of WireMock configuration</a></li>
<li><a href="#_generating_stubs_using_rest_docs">Generating Stubs using REST Docs</a></li>
<li><a href="#_generating_contracts_by_using_rest_docs">Generating Contracts by Using REST Docs</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div class="sect1">
<h2 id="_spring_cloud_contract_wiremock"><a class="link" href="#_spring_cloud_contract_wiremock">Spring Cloud Contract WireMock</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Spring Cloud Contract WireMock modules let you use <a href="https://github.com/tomakehurst/wiremock">WireMock</a> in a
Spring Boot application. Check out the
<a href="https://github.com/spring-cloud/spring-cloud-contract/tree/{branch}/samples">samples</a>
for more details.</p>
</div>
<div class="paragraph">
<p>If you have a Spring Boot application that uses Tomcat as an embedded server (which is
the default with <code>spring-boot-starter-web</code>), you can add
<code>spring-cloud-starter-contract-stub-runner</code> to your classpath and add <code>@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>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
public class WiremockForDocsTests {
// A service that calls out over HTTP
@Autowired
private Service service;
@Before
public void setup() {
this.service.setBase("http://localhost:"
+ this.environment.getProperty("wiremock.server.port"));
}
// Using the WireMock APIs in the normal way:
@Test
public void contextLoads() throws Exception {
// Stubbing WireMock
stubFor(get(urlEqualTo("/resource")).willReturn(aResponse()
.withHeader("Content-Type", "text/plain").withBody("Hello World!")));
// We're asserting if WireMock responded properly
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To start the stub server on a different port use (for example),
<code>@AutoConfigureWireMock(port=9999)</code>. For a random port, use a value of <code>0</code>. The stub
server port can be bound in the test application context with the "wiremock.server.port"
property. Using <code>@AutoConfigureWireMock</code> adds a bean of type <code>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. Also you can inject a bean of type <code>WireMockServer</code> into your test.</p>
</div>
<div class="sect2">
<h3 id="_registering_stubs_automatically"><a class="link" href="#_registering_stubs_automatically">Registering Stubs Automatically</a></h3>
<div class="paragraph">
<p>If you use <code>@AutoConfigureWireMock</code>, it registers WireMock JSON stubs from the file
system or classpath (by default, from <code>file:src/test/resources/mappings</code>). You can
customize the locations using the <code>stubs</code> attribute in the annotation, which can be an
Ant-style resource pattern or a directory. In the case of a directory, <code><strong>*/</strong>.json</code> is
appended. The following code shows an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureWireMock(stubs="classpath:/stubs")
public class WiremockImportApplicationTests {
@Autowired
private Service service;
@Test
public void contextLoads() throws Exception {
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Actually, WireMock always loads mappings from <code>src/test/resources/mappings</code> <strong>as
well as</strong> 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.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you&#8217;re using Spring Cloud Contract&#8217;s default stub jars, then your
stubs are stored under <code>/META-INF/group-id/artifact-id/versions/mappings/</code> folder. If you want to register all stubs from that location, from all embedded JARs, then it&#8217;s enough to use the following syntax.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@AutoConfigureWireMock(port = 0, stubs = "classpath*:/META-INF/**/mappings/**/*.json")</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_using_files_to_specify_the_stub_bodies"><a class="link" href="#_using_files_to_specify_the_stub_bodies">Using Files to Specify the Stub Bodies</a></h3>
<div class="paragraph">
<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>bodyFileName</code> instead of a
(literal) <code>body</code>. The files are resolved relative to a root directory (by default,
<code>src/test/resources/__files</code>). To customize this location you can set the <code>files</code>
attribute in the <code>@AutoConfigureWireMock</code> annotation to the location of the parent
directory (in other words, <code>__files</code> is a subdirectory). You can use Spring resource
notation to refer to <code>file:&#8230;&#8203;</code> or <code>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>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When you configure the <code>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>files</code> has no
effect on the stubs loaded explicitly from the <code>stubs</code> attribute.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_alternative_using_junit_rules"><a class="link" href="#_alternative_using_junit_rules">Alternative: Using JUnit Rules</a></h3>
<div class="paragraph">
<p>For a more conventional WireMock experience, you can use JUnit <code>@Rules</code> to start and stop
the server. To do so, use the <code>WireMockSpring</code> convenience class to obtain an <code>Options</code>
instance, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class WiremockForDocsClassRuleTests {
// Start WireMock on some dynamic port
// for some reason `dynamicPort()` is not working properly
@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(
WireMockSpring.options().dynamicPort());
// A service that calls out over HTTP to wiremock's port
@Autowired
private Service service;
@Before
public void setup() {
this.service.setBase("http://localhost:" + wiremock.port());
}
// Using the WireMock APIs in the normal way:
@Test
public void contextLoads() throws Exception {
// Stubbing WireMock
wiremock.stubFor(get(urlEqualTo("/resource")).willReturn(aResponse()
.withHeader("Content-Type", "text/plain").withBody("Hello World!")));
// We're asserting if WireMock responded properly
assertThat(this.service.go()).isEqualTo("Hello World!");
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>@ClassRule</code> means that the server shuts down after all the methods in this class
have been run.</p>
</div>
</div>
<div class="sect2">
<h3 id="_relaxed_ssl_validation_for_rest_template"><a class="link" href="#_relaxed_ssl_validation_for_rest_template">Relaxed SSL Validation for Rest Template</a></h3>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<p>To make this work with minimum fuss, you need to be using the Spring Boot
<code>RestTemplateBuilder</code> in your app, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>You need <code>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>@AutoConfigureWireMock</code>
annotation or the stub runner. If you use the JUnit <code>@Rule</code> approach, you need to add the
<code>@AutoConfigureHttpClient</code> annotation as well, as shown in the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest("app.baseUrl=https://localhost:6443")
@AutoConfigureHttpClient
public class WiremockHttpsServerApplicationTests {
@ClassRule
public static WireMockClassRule wiremock = new WireMockClassRule(
WireMockSpring.options().httpsPort(6443));
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are using <code>spring-boot-starter-test</code>, you have the Apache HTTP client on the
classpath and it is selected by the <code>RestTemplateBuilder</code> and configured to ignore SSL
errors. If you use the default <code>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="paragraph">
<p>To disable the custom <code>RestTemplateBuilder</code>, set the <code>wiremock.rest-template-ssl-enabled</code>
property to <code>false</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_wiremock_and_spring_mvc_mocks"><a class="link" href="#_wiremock_and_spring_mvc_mocks">WireMock and Spring MVC Mocks</a></h3>
<div class="paragraph">
<p>Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into
a Spring <code>MockRestServiceServer</code>. The following code shows an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE)
public class WiremockForDocsMockServerApplicationTests {
@Autowired
private RestTemplate restTemplate;
@Autowired
private Service service;
@Test
public void contextLoads() throws Exception {
// will read stubs classpath
MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate)
.baseUrl("https://example.org").stubs("classpath:/stubs/resource.json")
.build();
// We're asserting if WireMock responded properly
assertThat(this.service.go()).isEqualTo("Hello World");
server.verify();
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>baseUrl</code> value is prepended to all mock calls, and the <code>stubs()</code> method takes a stub
path resource pattern as an argument. In the preceding example, the stub defined at
<code>/stubs/resource.json</code> is loaded into the mock server. If the <code>RestTemplate</code> is asked to
visit <code><a href="https://example.org/" class="bare">https://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 href="https://wiremock.org/docs/stubbing/">WireMock website</a>.</p>
</div>
<div class="paragraph">
<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>
<div class="sect2">
<h3 id="_customization_of_wiremock_configuration"><a class="link" href="#_customization_of_wiremock_configuration">Customization of WireMock configuration</a></h3>
<div class="paragraph">
<p>You can register a bean of <code>org.springframework.cloud.contract.wiremock.WireMockConfigurationCustomizer</code> type
in order to customize the WireMock configuration (e.g. add custom transformers).
Example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> @Bean
WireMockConfigurationCustomizer optionsCustomizer() {
return new WireMockConfigurationCustomizer() {
@Override
public void customize(WireMockConfiguration options) {
// perform your customization here
}
};
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_generating_stubs_using_rest_docs"><a class="link" href="#_generating_stubs_using_rest_docs">Generating Stubs using REST Docs</a></h3>
<div class="paragraph">
<p><a href="https://projects.spring.io/spring-restdocs">Spring REST Docs</a> can be used to generate
documentation (for example in Asciidoctor format) for an HTTP API with Spring MockMvc
or <code>WebTestClient</code> 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>@AutoConfigureRestDocs</code> to have stubs be
automatically generated in the REST Docs output directory. The following code shows an
example using <code>MockMvc</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureRestDocs(outputDir = "target/snippets")
@AutoConfigureMockMvc
public class ApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
public void contextLoads() throws Exception {
mockMvc.perform(get("/resource"))
.andExpect(content().string("Hello World"))
.andDo(document("resource"));
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>This test generates a WireMock stub at "target/snippets/stubs/resource.json". It matches
all GET requests to the "/resource" path. The same example with <code>WebTestClient</code> (used
for testing Spring WebFlux applications) would look like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureRestDocs(outputDir = "target/snippets")
@AutoConfigureWebTestClient
public class ApplicationTests {
@Autowired
private WebTestClient client;
@Test
public void contextLoads() throws Exception {
client.get().uri("/resource").exchange()
.expectBody(String.class).isEqualTo("Hello World")
.consumeWith(document("resource"));
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Without any additional configuration, these tests 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. Doing so has two effects:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Creating a stub that matches only in the way you specify.</p>
</li>
<li>
<p>Asserting that the request in the test case also matches the same conditions.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The main entry point for this feature is <code>WireMockRestDocs.verify()</code>, which can be used
as a substitute for the <code>document()</code> convenience method, as shown in the following
example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import static org.springframework.cloud.contract.wiremock.restdocs.WireMockRestDocs.verify;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre>@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureRestDocs(outputDir = "target/snippets")
@AutoConfigureMockMvc
public class ApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
public void contextLoads() throws Exception {
mockMvc.perform(post("/resource")
.content("{\"id\":\"123456\",\"message\":\"Hello World\"}"))
.andExpect(status().isOk())
.andDo(verify().jsonPath("$.id")
.stub("resource"));
}
}</pre>
</div>
</div>
<div class="paragraph">
<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>.jsonPath()</code> to add additional
matchers. If JSON Path is unfamiliar, The <a href="https://github.com/jayway/JsonPath">JayWay
documentation</a> can help you get up to speed. The <code>WebTestClient</code> version of this test
has a similar <code>verify()</code> static helper that you insert in the same place.</p>
</div>
<div class="paragraph">
<p>Instead of the <code>jsonPath</code> and <code>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>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Test
public void contextLoads() throws Exception {
mockMvc.perform(post("/resource")
.content("{\"id\":\"123456\",\"message\":\"Hello World\"}"))
.andExpect(status().isOk())
.andDo(verify()
.wiremock(WireMock.post(
urlPathEquals("/resource"))
.withRequestBody(matchingJsonPath("$.id"))
.stub("post-resource"));
}</code></pre>
</div>
</div>
<div class="paragraph">
<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>
</div>
<div class="listingblock">
<div class="title">post-resource.json</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">{
"request" : {
"url" : "/resource",
"method" : "POST",
"bodyPatterns" : [ {
"matchesJsonPath" : "$.id"
}]
},
"response" : {
"status" : 200,
"body" : "Hello World",
"headers" : {
"X-Application-Context" : "application:-1",
"Content-Type" : "text/plain"
}
}
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You can use either the <code>wiremock()</code> method or the <code>jsonPath()</code> and <code>contentType()</code>
methods to create request matchers, but you can&#8217;t use both approaches.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>On the consumer side, you can make the <code>resource.json</code> generated earlier in this section
available on the classpath (by
&lt;&lt;publishing-stubs-as-jars], for example). After that, you can create a stub using WireMock in a
number of different ways, including by using
<code>@AutoConfigureWireMock(stubs="classpath:resource.json")</code>, as described earlier in this
document.</p>
</div>
</div>
<div class="sect2">
<h3 id="_generating_contracts_by_using_rest_docs"><a class="link" href="#_generating_contracts_by_using_rest_docs">Generating Contracts by Using REST Docs</a></h3>
<div class="paragraph">
<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>
</div>
<div class="paragraph">
<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>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
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.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Consider the following test:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> this.mockMvc
.perform(post("/foo").accept(MediaType.APPLICATION_PDF)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content("{\"foo\": 23, \"bar\" : \"baz\" }"))
.andExpect(status().isOk()).andExpect(content().string("bar"))
// first WireMock
.andDo(WireMockRestDocs.verify().jsonPath("$[?(@.foo &gt;= 20)]")
.jsonPath("$[?(@.bar in ['baz','bazz','bazzz'])]")
.contentType(MediaType.valueOf("application/json"))
.stub("shouldGrantABeerIfOldEnough"))
// then Contract DSL documentation
.andDo(document("index", SpringCloudContractRestDocs.dslContract()));</code></pre>
</div>
</div>
<div class="paragraph">
<p>The preceding test creates the stub presented in the previous section, generating both
the contract and a documentation file.</p>
</div>
<div class="paragraph">
<p>The contract is called <code>index.groovy</code> and might look like the following example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-groovy hljs" data-lang="groovy">import org.springframework.cloud.contract.spec.Contract
Contract.make {
request {
method 'POST'
url '/foo'
body('''
{"foo": 23 }
''')
headers {
header('''Accept''', '''application/json''')
header('''Content-Type''', '''application/json''')
}
}
response {
status OK()
body('''
bar
''')
headers {
header('''Content-Type''', '''application/json;charset=UTF-8''')
header('''Content-Length''', '''3''')
}
testMatchers {
jsonPath('$[?(@.foo &gt;= 20)]', byType())
}
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The generated document (formatted in Asciidoc in this case) contains a formatted
contract. The location of this file would be <code>index/dsl-contract.adoc</code>.</p>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
<script type="text/javascript" src="js/toc.js"></script>
<link rel="stylesheet" href="js/highlight/styles/atom-one-dark-reasonable.min.css">
<script src="js/highlight/highlight.min.js"></script>
<script>hljs.initHighlighting()</script>
</body>
</html>