Sync docs from 2.0.x to gh-pages
This commit is contained in:
@@ -13,6 +13,6 @@
|
||||
== Pick The Documentation Option
|
||||
|
||||
- link:single/{docs-main}.html[Single HTML]
|
||||
- link:multi/{docs-main}.html[Multi HTML]</echo>
|
||||
- link:multi/multi_{docs-main}.html[Multi HTML]</echo>
|
||||
</target>
|
||||
</project>
|
||||
@@ -1,2 +1,2 @@
|
||||
#Tue Aug 29 10:05:43 CEST 2017
|
||||
configuration*?=EB4133EE3A71541EAE82738A940612CD099BE89F
|
||||
#Tue Aug 29 11:49:40 CEST 2017
|
||||
configuration*?=80C9A2DEBCA17C3B63DE5D7B40DD74AFA6E32FA1
|
||||
|
||||
@@ -16,5 +16,8 @@
|
||||
</module>
|
||||
<module name="UnusedImports"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck" >
|
||||
<property name="illegalPkgs" value="com.google.common"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<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.3">
|
||||
<meta name="generator" content="Asciidoctor 1.5.5">
|
||||
<title>spring-cloud-contract</title>
|
||||
<link rel="stylesheet" href="css/manual-singlepage.css">
|
||||
<style>
|
||||
@@ -103,7 +103,7 @@ $(addBlockSwitches);
|
||||
<p><a href="single/spring-cloud-contract.html">Single HTML</a></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="multi/spring-cloud-contract.html">Multi HTML</a></p>
|
||||
<p><a href="multi/multi_spring-cloud-contract.html">Multi HTML</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
53
2.0.x/multi/multi__generating_contracts_using_restdocs.html
Normal file
53
2.0.x/multi/multi__generating_contracts_using_restdocs.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>7. Generating Contracts using RestDocs</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__generating_stubs_using_restdocs.html" title="6. Generating Stubs using RestDocs"><link rel="next" href="multi__migrations.html" title="8. 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">7. Generating Contracts using RestDocs</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__generating_stubs_using_restdocs.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <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="_generating_contracts_using_restdocs" href="#_generating_contracts_using_restdocs"></a>7. Generating Contracts using RestDocs</h1></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’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’s why we suggest to do both.</p></td></tr></table></div><p>Let’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>)
|
||||
.accept(MediaType.APPLICATION_PDF)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\"foo\": 23 }"</span>))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"bar"</span>))
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// first WireMock</span>
|
||||
.andDo(WireMockRestDocs.verify()
|
||||
.jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.foo >= 20)]"</span>)
|
||||
.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
|
||||
|
||||
Contract.make {
|
||||
request {
|
||||
method <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'POST'</span>
|
||||
url <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'/foo'</span>
|
||||
body(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'
|
||||
</span> {<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"foo"</span>: <span class="hl-number">23</span> }
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">')
|
||||
</span> headers {
|
||||
header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'Accept'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'application/json'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>)
|
||||
header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'Content-Type'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'application/json'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>)
|
||||
}
|
||||
}
|
||||
response {
|
||||
status <span class="hl-number">200</span>
|
||||
body(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'
|
||||
</span> bar
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">')
|
||||
</span> headers {
|
||||
header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'Content-Type'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'application/json;charset=UTF-8'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>)
|
||||
header(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'Content-Length'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'3'</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span>)
|
||||
}
|
||||
testMatchers {
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$[?(@.foo >= 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 class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__generating_stubs_using_restdocs.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__migrations.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6. Generating Stubs using RestDocs </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"> 8. Migrations</td></tr></table></div></body></html>
|
||||
93
2.0.x/multi/multi__generating_stubs_using_restdocs.html
Normal file
93
2.0.x/multi/multi__generating_stubs_using_restdocs.html
Normal file
@@ -0,0 +1,93 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>6. Generating Stubs using RestDocs</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__wiremock_and_spring_mvc_mocks.html" title="5. WireMock and Spring MVC Mocks"><link rel="next" href="multi__generating_contracts_using_restdocs.html" title="7. Generating Contracts using RestDocs"></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">6. Generating Stubs using RestDocs</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__wiremock_and_spring_mvc_mocks.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__generating_contracts_using_restdocs.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_generating_stubs_using_restdocs" href="#_generating_stubs_using_restdocs"></a>6. Generating Stubs using RestDocs</h1></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>
|
||||
<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>
|
||||
<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> ApplicationTests {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> MockMvc mockMvc;
|
||||
|
||||
<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(get(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span>))
|
||||
.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
|
||||
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>
|
||||
<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> ApplicationTests {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> MockMvc mockMvc;
|
||||
|
||||
<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>))
|
||||
.andExpect(status().isOk())
|
||||
.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>
|
||||
<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>))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(verify()
|
||||
.wiremock(WireMock.post(
|
||||
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. </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>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"method"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"POST"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"bodyPatterns"</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>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.id"</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>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span> : <span class="hl-number">200</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"X-Application-Context"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application:-1"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"text/plain"</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>
|
||||
<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="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__wiremock_and_spring_mvc_mocks.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__generating_contracts_using_restdocs.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. WireMock and Spring MVC Mocks </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"> 7. Generating Contracts using RestDocs</td></tr></table></div></body></html>
|
||||
83
2.0.x/multi/multi__migrations.html
Normal file
83
2.0.x/multi/multi__migrations.html
Normal file
@@ -0,0 +1,83 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>8. Migrations</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__generating_contracts_using_restdocs.html" title="7. Generating Contracts using RestDocs"></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">8. Migrations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__generating_contracts_using_restdocs.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> </td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_migrations" href="#_migrations"></a>8. Migrations</h1></div></div></div><p>In the following document we will write about necessary migration steps between versions.</p><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_1_0_x_1_1_x" href="#_1_0_x_1_1_x"></a>8.1 1.0.x → 1.1.x</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_new_structure_of_generated_stubs" href="#_new_structure_of_generated_stubs"></a>8.1.1 New structure of generated stubs</h3></div></div></div><p>In <code class="literal">1.1.x</code> we have introduced a changed structure of generated stubs. So if you’ve
|
||||
been using the following <code class="literal">@AutoConfigureWireMock</code> notation to use the stubs from classpath</p><pre class="programlisting">@AutoConfigureWireMock(stubs = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"classpath:/customer-stubs/mappings"</span>, port = <span class="hl-number">8084</span>)</pre><p>It will no longer work with the new stubs. You have to either change the location of stubs
|
||||
to : <code class="literal">classpath:…​/META-INF/groupId/artifactId/version/mappings</code> as follows</p><pre class="programlisting">@AutoConfigureWireMock(stubs = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"classpath:customer-stubs/META-INF/travel.components/customer-contract/1.0.2-SNAPSHOT/mappings/"</span>, port = <span class="hl-number">8084</span>)</pre><p>Or migrate to the new classpath based <code class="literal">@AutoConfigureStubRunner</code>.</p><p>If however you don’t want to do that and you want to remain with the old structure
|
||||
just set your plugin tasks accordingly. Example for the structure presented in the
|
||||
snippet above.</p><p class="primary"><b>Maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- start of pom.xml --></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><properties></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- we don't want the verifier to do a jar for us --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><spring.cloud.contract.verifier.skip></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></spring.cloud.contract.verifier.skip></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></properties></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- ... --></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- You need to set up the assembly plugin --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><build></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugins></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.maven.plugins<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>maven-assembly-plugin<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><id></span>stub<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></id></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><phase></span>prepare-package<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></phase></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goal></span>single<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goal></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><inherited></span>false<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></inherited></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><attach></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></attach></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><descriptor></span>${basedir}/src/assembly/stub.xml<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></descriptor></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugins></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></build></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- end of pom.xml --></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- start of stub.xml--></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><assembly</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns:xsi</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xsi:schemaLocation</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><id></span>stubs<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></id></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><formats></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><format></span>jar<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></format></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></formats></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includeBaseDirectory></span>false<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includeBaseDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSets></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>${project.build.directory}/snippets/stubs<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>customer-stubs/mappings<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**/*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>${basedir}/src/test/resources/contracts<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>customer-stubs/contracts<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**/*.groovy<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSets></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></assembly></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- end of stub.xml--></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">task copyStubs(type: Copy, dependsOn: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'generateWireMockClientStubs'</span>) {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Preserve directory structure from 1.0.X of spring-cloud-contract</span>
|
||||
from <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"${project.buildDir}/resources/main/customer-stubs/META-INF/${project.group}/${project.name}/${project.version}"</span>
|
||||
into <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"${project.buildDir}/resources/main/customer-stubs"</span>
|
||||
}</pre><p class="secondary">
|
||||
</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_1_1_x_1_2_x" href="#_1_1_x_1_2_x"></a>8.2 1.1.x → 1.2.x</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_custom_literal_httpserverstub_literal" href="#_custom_literal_httpserverstub_literal"></a>8.2.1 Custom <code class="literal">HttpServerStub</code></h3></div></div></div><p>By introducing a method <code class="literal">String registeredMappings()</code> in the public interface
|
||||
<code class="literal">HttpServerStub</code>, if you wrote a custom <code class="literal">HttpServerStub</code> implementation, you’ll
|
||||
have to implement that method too. It should return a <code class="literal">String</code> representing
|
||||
all mappings available in a single <code class="literal">HttpServerStub</code>. Related to
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-contract/issues/355" target="_top">issue 355</a>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_new_packages_for_generated_tests" href="#_new_packages_for_generated_tests"></a>8.2.2 New packages for generated tests</h3></div></div></div><p>The flow for setting the generated tests package name will look like this:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">pick <code class="literal">basePackageForTests</code></li><li class="listitem">if <code class="literal">basePackageForTests</code> wasn’t set pick the package from <code class="literal">baseClassForTests</code></li><li class="listitem">if <code class="literal">baseClassForTests</code> wasn’t set pick <code class="literal">packageWithBaseClasses</code></li><li class="listitem">if nothing got set pick the default <code class="literal">org.springframework.cloud.contract.verifier.tests</code> value</li></ul></div><p>Related to
|
||||
<a class="link" href="https://github.com/spring-cloud/spring-cloud-contract/issues/260" target="_top">issue 260</a>.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__generating_contracts_using_restdocs.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">7. Generating Contracts using RestDocs </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"> </td></tr></table></div></body></html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>4. Relaxed SSL Validation for Rest Template</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__spring_cloud_contract_wiremock.html" title="3. Spring Cloud Contract WireMock"><link rel="next" href="multi__wiremock_and_spring_mvc_mocks.html" title="5. WireMock and Spring MVC Mocks"></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">4. Relaxed SSL Validation for Rest Template</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__spring_cloud_contract_wiremock.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__wiremock_and_spring_mvc_mocks.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_relaxed_ssl_validation_for_rest_template" href="#_relaxed_ssl_validation_for_rest_template"></a>4. Relaxed SSL Validation for Rest Template</h1></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’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’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>
|
||||
<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>
|
||||
<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 {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@ClassRule</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">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’t need the annotation (but it won’t do any harm). There is no support currently for other clients, but
|
||||
it may be added in future releases.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__spring_cloud_contract_wiremock.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__wiremock_and_spring_mvc_mocks.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3. Spring Cloud Contract WireMock </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"> 5. WireMock and Spring MVC Mocks</td></tr></table></div></body></html>
|
||||
6
2.0.x/multi/multi__spring_cloud_contract.html
Normal file
6
2.0.x/multi/multi__spring_cloud_contract.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>1. Spring Cloud Contract</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_pr01.html" title=""><link rel="next" href="multi__spring_cloud_contract_verifier.html" title="2. Spring Cloud Contract Verifier"></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">1. Spring Cloud Contract</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_pr01.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract_verifier.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_spring_cloud_contract" href="#_spring_cloud_contract"></a>1. Spring Cloud Contract</h1></div></div></div><p>What you always need is confidence in pushing new features into a new application or service in a distributed system.
|
||||
This project provides support for Consumer Driven Contracts and service schemas in Spring applications, covering a
|
||||
range of options for writing tests, publishing them as assets, asserting that a contract is kept by producers
|
||||
and consumers, for HTTP and message-based interactions.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_pr01.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract_verifier.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </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"> 2. Spring Cloud Contract Verifier</td></tr></table></div></body></html>
|
||||
4155
2.0.x/multi/multi__spring_cloud_contract_verifier.html
Normal file
4155
2.0.x/multi/multi__spring_cloud_contract_verifier.html
Normal file
File diff suppressed because one or more lines are too long
92
2.0.x/multi/multi__spring_cloud_contract_wiremock.html
Normal file
92
2.0.x/multi/multi__spring_cloud_contract_wiremock.html
Normal file
@@ -0,0 +1,92 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>3. 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__spring_cloud_contract_verifier.html" title="2. Spring Cloud Contract Verifier"><link rel="next" href="multi__relaxed_ssl_validation_for_rest_template.html" title="4. Relaxed SSL Validation for Rest Template"></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">3. Spring Cloud Contract WireMock</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__spring_cloud_contract_verifier.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__relaxed_ssl_validation_for_rest_template.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>3. 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> with different servers by using the
|
||||
"ambient" server embedded 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><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>The Spring Cloud Release Train BOM imports <code class="literal">spring-cloud-contract-dependencies</code>
|
||||
which in turn has exclusions for the dependencies needed by WireMock. This might lead to a situation that
|
||||
even if you’re not using Spring Cloud Contract then your dependencies will be influenced
|
||||
anyways.</p></td></tr></table></div><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’s a simple 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 {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// A service that calls out over HTTP</span>
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> Service service;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Using the WireMock APIs in the normal way:</span>
|
||||
<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 {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Stubbing WireMock</span>
|
||||
stubFor(get(urlEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span>))
|
||||
.willReturn(aResponse().withHeader(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"text/plain"</span>).withBody(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World!"</span>)));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// We're asserting if WireMock responded properly</span>
|
||||
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>3.1 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)
|
||||
@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 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>3.2 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:…​</code> or <code class="literal">classpath:…​</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>3.3 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>
|
||||
<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 {
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Start WireMock on some dynamic port</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// for some reason `dynamicPort()` is not working properly</span>
|
||||
<em><span class="hl-annotation" style="color: gray">@ClassRule</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">static</span> WireMockClassRule wiremock = <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> WireMockClassRule(
|
||||
WireMockSpring.options().dynamicPort());
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// A service that calls out over HTTP to localhost:${wiremock.port}</span>
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> Service service;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Using the WireMock APIs in the normal way:</span>
|
||||
<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 {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// Stubbing WireMock</span>
|
||||
wiremock.stubFor(get(urlEqualTo(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/resource"</span>))
|
||||
.willReturn(aResponse().withHeader(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span>, <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"text/plain"</span>).withBody(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Hello World!"</span>)));
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// We're asserting if WireMock responded properly</span>
|
||||
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><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__spring_cloud_contract_verifier.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__relaxed_ssl_validation_for_rest_template.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. Spring Cloud Contract Verifier </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"> 4. Relaxed SSL Validation for Rest Template</td></tr></table></div></body></html>
|
||||
37
2.0.x/multi/multi__wiremock_and_spring_mvc_mocks.html
Normal file
37
2.0.x/multi/multi__wiremock_and_spring_mvc_mocks.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>5. WireMock and Spring MVC Mocks</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__relaxed_ssl_validation_for_rest_template.html" title="4. Relaxed SSL Validation for Rest Template"><link rel="next" href="multi__generating_stubs_using_restdocs.html" title="6. Generating Stubs using RestDocs"></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">5. WireMock and Spring MVC Mocks</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi__relaxed_ssl_validation_for_rest_template.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__generating_stubs_using_restdocs.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="_wiremock_and_spring_mvc_mocks" href="#_wiremock_and_spring_mvc_mocks"></a>5. WireMock and Spring MVC Mocks</h1></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’s 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 {
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> RestTemplate restTemplate;
|
||||
|
||||
<em><span class="hl-annotation" style="color: gray">@Autowired</span></em>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">private</span> Service service;
|
||||
|
||||
<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 {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// will read stubs classpath</span>
|
||||
MockRestServiceServer server = WireMockRestServiceServer.with(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">this</span>.restTemplate)
|
||||
.baseUrl(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"http://example.org"</span>).stubs(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"classpath:/stubs/resource.json"</span>)
|
||||
.build();
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// We're asserting if WireMock responded properly</span>
|
||||
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="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi__relaxed_ssl_validation_for_rest_template.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__generating_stubs_using_restdocs.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Relaxed SSL Validation for Rest Template </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"> 6. Generating Stubs using RestDocs</td></tr></table></div></body></html>
|
||||
4
2.0.x/multi/multi_pr01.html
Normal file
4
2.0.x/multi/multi_pr01.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title></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_spring-cloud-contract.html" title="Spring Cloud Contract"><link rel="next" href="multi__spring_cloud_contract.html" title="1. Spring Cloud Contract"></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"></th></tr><tr><td width="20%" align="left"><a accesskey="p" href="multi_spring-cloud-contract.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract.html">Next</a></td></tr></table><hr></div><div class="preface"><div class="titlepage"><div><div><h1 class="title"><a name="d0e9" href="#d0e9"></a></h1></div></div></div><p><span class="emphasis"><em>Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak,
|
||||
Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer</em></span></p><p>2.0.0.BUILD-SNAPSHOT</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_spring-cloud-contract.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__spring_cloud_contract.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Spring Cloud Contract </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"> 1. Spring Cloud Contract</td></tr></table></div></body></html>
|
||||
3
2.0.x/multi/multi_spring-cloud-contract.html
Normal file
3
2.0.x/multi/multi_spring-cloud-contract.html
Normal file
File diff suppressed because one or more lines are too long
@@ -376,7 +376,9 @@ git merge --no-ff contract-change-pr
|
||||
git push origin master</pre><p>Then we assume that your CI would run sth like <code class="literal">./mvnw clean deploy</code> which would publish both the application and the stub artifcats.</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_consumer_side_loan_issuance_final_step" href="#_consumer_side_loan_issuance_final_step"></a>Consumer side (Loan Issuance) final step</h4></div></div></div><p>As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):</p><p><span class="strong"><strong>merge branch to master</strong></span></p><pre class="programlisting">git checkout master
|
||||
git merge --no-ff contract-change-pr</pre><p><span class="strong"><strong>work online</strong></span></p><p>Now you can disable the offline work for Spring Cloud Contract Stub Runner and provide where the repository with your stubs is placed. At this moment the stubs of the server side will be automatically downloaded from Nexus / Artifactory.
|
||||
You can switch off the value of the <code class="literal">workOffline</code> parameter in your annotation. Below you can see an
|
||||
example of achieving the same by changing the properties.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">link</span>:https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/<span class="hl-number">2.0</span>.x/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">[]</span></pre><p>And that’s it!</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_dependencies" href="#_dependencies"></a>2.1.5 Dependencies</h3></div></div></div><p>The best way to add the dependencies is to just use the proper <code class="literal">starter</code> dependency.</p><p>For <code class="literal">stub-runner</code> use <code class="literal">spring-cloud-starter-stub-runner</code> and when you’re using a plugin just add
|
||||
example of achieving the same by changing the properties.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">stubrunner</span>:
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> ids</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'com.example:http-server-dsl:+:stubs:8080'</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute"> repositoryRoot</span>: http://repo.spring.io/libs-snapshot</pre><p>And that’s it!</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_dependencies" href="#_dependencies"></a>2.1.5 Dependencies</h3></div></div></div><p>The best way to add the dependencies is to just use the proper <code class="literal">starter</code> dependency.</p><p>For <code class="literal">stub-runner</code> use <code class="literal">spring-cloud-starter-stub-runner</code> and when you’re using a plugin just add
|
||||
<code class="literal">spring-cloud-starter-contract-verifier</code>.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_additional_links" href="#_additional_links"></a>2.1.6 Additional links</h3></div></div></div><p>Below you can find some resources related to Spring Cloud Contract Verifier and Stub Runner. Note that some can be outdated since the Spring Cloud Contract Verifier project
|
||||
is under constant development.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_spring_cloud_contract_video" href="#_spring_cloud_contract_video"></a>Spring Cloud Contract video</h4></div></div></div><p>You can check out the video from the Warsaw JUG about Spring Cloud Contract:</p></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_readings" href="#_readings"></a>Readings</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><a class="link" href="http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura" target="_top">Slides from Marcin Grzejszczak’s talk about Accurest</a></li><li class="listitem"><a class="link" href="http://toomuchcoding.com/blog/categories/accurest/" target="_top">Accurest related articles from Marcin Grzejszczak’s blog</a></li><li class="listitem"><a class="link" href="http://toomuchcoding.com/blog/categories/spring-cloud-contract/" target="_top">Spring Cloud Contract related articles from Marcin Grzejszczak’s blog</a></li><li class="listitem"><a class="link" href="http://groovy-lang.org/json.html" target="_top">Groovy docs regarding JSON</a></li></ul></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_samples" href="#_samples"></a>2.1.7 Samples</h3></div></div></div><p>Here you can find some <a class="link" href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples" target="_top">samples</a>.</p></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_faq" href="#_faq"></a>2.2 FAQ</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_why_use_spring_cloud_contract_verifier_and_not_x" href="#_why_use_spring_cloud_contract_verifier_and_not_x"></a>2.2.1 Why use Spring Cloud Contract Verifier and not X ?</h3></div></div></div><p>For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you’re already creating
|
||||
software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make
|
||||
@@ -1410,13 +1412,71 @@ automatically for you.</p><div class="section"><div class="titlepage"><div><div>
|
||||
}</pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_publishing_stubs_as_jars" href="#_publishing_stubs_as_jars"></a>2.5.2 Publishing stubs as JARs</h3></div></div></div><p>The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository.</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>For both Maven and Gradle the setup comes out of the box. But you can customize it if you want to.</p></td></tr></table></div><p class="primary"><b>Maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- First disable the default jar setup in the properties section--></span>
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/pom.xml[]
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- we don't want the verifier to do a jar for us --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><spring.cloud.contract.verifier.skip></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></spring.cloud.contract.verifier.skip></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- Next add the assembly plugin to your build --></span>
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/pom.xml[]
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- we want the assembly plugin to generate the JAR --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.apache.maven.plugins<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>maven-assembly-plugin<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><id></span>stub<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></id></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><phase></span>prepare-package<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></phase></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goal></span>single<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goal></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><inherited></span>false<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></inherited></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><attach></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></attach></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><descriptor></span>${basedir}/src/assembly/stub.xml<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></descriptor></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span>
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- Finally setup your assembly. Below you can find the contents of src/main/assembly/stub.xml --></span>
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/src/assembly/stub.xml[]</pre><p class="primary">
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><assembly</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xmlns:xsi</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-attribute">xsi:schemaLocation</span>=<span xmlns:d="http://docbook.org/ns/docbook" class="hl-value">"http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag">></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><id></span>stubs<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></id></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><formats></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><format></span>jar<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></format></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></formats></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includeBaseDirectory></span>false<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includeBaseDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSets></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>src/main/java<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>/<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**com/example/model/*.*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>${project.build.directory}/classes<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>/<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**com/example/model/*.*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>${project.build.directory}/snippets/stubs<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>META-INF/${project.groupId}/${project.artifactId}/${project.version}/mappings<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**/*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><directory></span>${basedir}/src/test/resources/contracts<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></directory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><outputDirectory></span>META-INF/${project.groupId}/${project.artifactId}/${project.version}/contracts<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></outputDirectory></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><include></span>**/*.groovy<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></include></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></includes></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSet></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></fileSets></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></assembly></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">ext {
|
||||
contractsDir = file(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"mappings"</span>)
|
||||
@@ -3429,18 +3489,217 @@ got the name of the contract file <code class="literal">WithList.groovy</code> p
|
||||
contract had index <code class="literal">1</code> in the list of contracts in the file).</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>As you can see it’s much better if you name your contracts since then your tests
|
||||
are far more meaningful.</p></td></tr></table></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_customization" href="#_customization"></a>2.18 Customization</h2></div></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_extending_the_dsl" href="#_extending_the_dsl"></a>2.18.1 Extending the DSL</h3></div></div></div><p>It is possible to provide your own functions to the DSL. The key requirement for this
|
||||
feature was to maintain the static compatibility. Below you will be able to see an example
|
||||
of:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">creation of a JAR with reusable classes</li><li class="listitem">referencing of these classes in the DSLs</li></ul></div><p>The full example can be found <a class="link" href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples" target="_top">here</a>.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_common_jar" href="#_common_jar"></a>Common JAR</h4></div></div></div><p>Below you can find three classes that we will reuse in the DSLs.</p><p><span class="strong"><strong>PatternUtils</strong></span> contains functions used by both the <span class="strong"><strong>consumer</strong></span> and the <span class="strong"><strong>producer</strong></span>.</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/PatternUtils.java[]</span></pre><p><span class="strong"><strong>ConsumerUtils</strong></span> contains functions used by the <span class="strong"><strong>consumer</strong></span>.</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/ConsumerUtils.java[]</span></pre><p><span class="strong"><strong>ProducerUtils</strong></span> contains functions used by the <span class="strong"><strong>producer</strong></span>.</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/ProducerUtils.java[]</span></pre></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_adding_the_dependency_to_project" href="#_adding_the_dependency_to_project"></a>Adding the dependency to project</h4></div></div></div><p>In order for the plugins and IDE to be able to reference the common JAR classes you need
|
||||
of:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">creation of a JAR with reusable classes</li><li class="listitem">referencing of these classes in the DSLs</li></ul></div><p>The full example can be found <a class="link" href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples" target="_top">here</a>.</p><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_common_jar" href="#_common_jar"></a>Common JAR</h4></div></div></div><p>Below you can find three classes that we will reuse in the DSLs.</p><p><span class="strong"><strong>PatternUtils</strong></span> contains functions used by both the <span class="strong"><strong>consumer</strong></span> and the <span class="strong"><strong>producer</strong></span>.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> com.example;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> java.util.regex.Pattern;
|
||||
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* If you want to use {@link Pattern} directly in your tests
|
||||
* then you can create a class resembling this one. It can
|
||||
* contain all the {@link Pattern} you want to use in the DSL.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* request {
|
||||
* body(
|
||||
* [ age: $(c(PatternUtils.oldEnough()))]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Notice that we're using both {@code $()} for dynamic values
|
||||
* and {@code c()} for the consumer side.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/</strong>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//tag::impl[]</span>
|
||||
<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> PatternUtils {
|
||||
|
||||
<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> String tooYoung() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::start[]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-1][0-9]"</span>;
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::end[return]</span>
|
||||
}
|
||||
|
||||
<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> Pattern oldEnough() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::start[]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> Pattern.compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[2-9][0-9]"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::end[return]</span>
|
||||
}
|
||||
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* Makes little sense but it's just an example ;)
|
||||
*/</strong>
|
||||
<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> Pattern ok() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::start[]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> Pattern.compile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"OK"</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::end[return]</span>
|
||||
}
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//end::impl[]</span></pre><p><span class="strong"><strong>ConsumerUtils</strong></span> contains functions used by the <span class="strong"><strong>consumer</strong></span>.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> com.example;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.internal.ClientDslProperty;
|
||||
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* DSL Properties passed to the DSL from the consumer's perspective.
|
||||
* That means that on the input side {@code Request} for HTTP
|
||||
* or {@code Input} for messaging you can have a regular expression.
|
||||
* On the {@code Response} for HTTP or {@code Output} for messaging
|
||||
* you have to have a concrete value.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/</strong>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//tag::impl[]</span>
|
||||
<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> ConsumerUtils {
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* Consumer side property. By using the {@link ClientDslProperty}
|
||||
* you can omit most of boilerplate code from the perspective
|
||||
* of dynamic values. Example
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* request {
|
||||
* body(
|
||||
* [ age: $(ConsumerUtils.oldEnough())]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* That way it's in the implementation that we decide what value we will pass to the consumer
|
||||
* and which one to the producer.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/</strong>
|
||||
<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> ClientDslProperty oldEnough() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::start[]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// this example is not the best one and</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// theoretically you could just pass the regex instead of `ServerDslProperty` but</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// it's just to show some new tricks :)</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> ClientDslProperty(PatternUtils.oldEnough(), <span class="hl-number">40</span>);
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//remove::end[return]</span>
|
||||
}
|
||||
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//end::impl[]</span></pre><p><span class="strong"><strong>ProducerUtils</strong></span> contains functions used by the <span class="strong"><strong>producer</strong></span>.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> com.example;
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.internal.ServerDslProperty;
|
||||
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* DSL Properties passed to the DSL from the producer's perspective.
|
||||
* That means that on the input side {@code Request} for HTTP
|
||||
* or {@code Input} for messaging you have to have a concrete value.
|
||||
* On the {@code Response} for HTTP or {@code Output} for messaging
|
||||
* you can have a regular expression.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/</strong>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//tag::impl[]</span>
|
||||
<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> ProducerUtils {
|
||||
|
||||
<strong class="hl-tag" style="color: blue">/**
|
||||
* Producer side property. By using the {@link ProducerUtils}
|
||||
* you can omit most of boilerplate code from the perspective
|
||||
* of dynamic values. Example
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* response {
|
||||
* body(
|
||||
* [ status: $(ProducerUtils.ok())]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* That way it's in the implementation that we decide what value we will pass to the consumer
|
||||
* and which one to the producer.
|
||||
*/</strong>
|
||||
<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> ServerDslProperty ok() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// this example is not the best one and</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// theoretically you could just pass the regex instead of `ServerDslProperty` but</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// it's just to show some new tricks :)</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> ServerDslProperty( PatternUtils.ok(), <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"OK"</span>);
|
||||
}
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//end::impl[]</span></pre></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_adding_the_dependency_to_project" href="#_adding_the_dependency_to_project"></a>Adding the dependency to project</h4></div></div></div><p>In order for the plugins and IDE to be able to reference the common JAR classes you need
|
||||
to pass the dependency to your project.</p><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_test_dependency_in_project_s_dependencies" href="#_test_dependency_in_project_s_dependencies"></a>Test dependency in project’s dependencies</h5></div></div></div><p>First add the common jar dependency as a test dependency. That way since your
|
||||
contracts files are available at test resources path, automatically the
|
||||
common jar classes will be visible in your Groovy files.</p><p class="primary"><b>Maven. </b>
|
||||
</p><pre class="programlisting">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/pom.xml[]</pre><p class="primary">
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>com.example<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>beer-common<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${project.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><scope></span>test<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></scope></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/build.gradle[]</span></pre><p class="secondary">
|
||||
</p><pre class="programlisting">testCompile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1-SNAPSHOT"</span>)</pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_test_dependency_in_plugin_s_dependencies" href="#_test_dependency_in_plugin_s_dependencies"></a>Test dependency in plugin’s dependencies</h5></div></div></div><p>Now you have to add the dependency for the plugin to reuse at runtime.</p><p class="primary"><b>Maven. </b>
|
||||
</p><pre class="programlisting">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/pom.xml[]</pre><p class="primary">
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-contract-maven-plugin<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${spring-cloud-contract.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><packageWithBaseClasses></span>com.example<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></packageWithBaseClasses></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassMappings></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractPackageRegex></span>.*intoxication.*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractPackageRegex></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassFQN></span>com.example.intoxication.BeerIntoxicationBase<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassFQN></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassMappings></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependencies></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>com.example<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>beer-common<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${project.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><scope></span>compile<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></scope></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependencies></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/build.gradle[]</span></pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_referencing_classes_in_dsls" href="#_referencing_classes_in_dsls"></a>Referencing classes in DSLs</h5></div></div></div><p>Now you can reference your classes in your DSL. Example:</p><pre class="programlisting">link:https:<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">//raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/src/test/resources/contracts/beer/rest/shouldGrantABeerIfOldEnough.groovy[]</span></pre></div></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_pluggable_architecture" href="#_pluggable_architecture"></a>2.19 Pluggable architecture</h2></div></div></div><p>There are cases where you have your contracts defined in other formats
|
||||
</p><pre class="programlisting">classpath <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1-SNAPSHOT"</span></pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h5 class="title"><a name="_referencing_classes_in_dsls" href="#_referencing_classes_in_dsls"></a>Referencing classes in DSLs</h5></div></div></div><p>Now you can reference your classes in your DSL. Example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> contracts.beer.rest
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.example.ConsumerUtils
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.example.ProducerUtils
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> org.springframework.cloud.contract.spec.Contract
|
||||
|
||||
Contract.make {
|
||||
description(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"
|
||||
</span>Represents a successful scenario of getting a beer
|
||||
|
||||
```
|
||||
given:
|
||||
client is old enough
|
||||
when:
|
||||
he applies <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">for</span> a beer
|
||||
then:
|
||||
we<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'ll grant him the beer
|
||||
</span>```
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">")
|
||||
</span> request {
|
||||
method <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'POST'</span>
|
||||
url <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'/check'</span>
|
||||
body(
|
||||
age: $(ConsumerUtils.oldEnough())
|
||||
)
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
response {
|
||||
status <span class="hl-number">200</span>
|
||||
body(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"
|
||||
</span> {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span>: <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"${value(ProducerUtils.ok())}"</span>
|
||||
}
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">""</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">")
|
||||
</span> headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}</pre></div></div></div></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="_pluggable_architecture" href="#_pluggable_architecture"></a>2.19 Pluggable architecture</h2></div></div></div><p>There are cases where you have your contracts defined in other formats
|
||||
like YAML, RAML or PACT. On the other hand you’d like to profit from
|
||||
the test and stubs generation. It’s really easy to add your own implementation
|
||||
of either of those. Also you can customize the way tests are generated (for example you can generate
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?asciidoc-toc maxdepth="3"?>
|
||||
<?asciidoc-numbered?>
|
||||
<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
|
||||
<book xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
|
||||
<info>
|
||||
<title>Spring Cloud Contract</title>
|
||||
<date>2017-08-29</date>
|
||||
@@ -24,7 +24,7 @@ and consumers, for HTTP and message-based interactions.</simpara>
|
||||
<section xml:id="_introduction">
|
||||
<title>Introduction</title>
|
||||
<tip>
|
||||
<simpara>The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (<link xlink:href="http://codearte.io">codearte.io</link>)</simpara>
|
||||
<simpara>The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (<link xl:href="http://codearte.io">codearte.io</link>)</simpara>
|
||||
</tip>
|
||||
<simpara>Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped
|
||||
with <emphasis>Contract Definition Language</emphasis> (DSL). Contract definitions are used to produce following resources:</simpara>
|
||||
@@ -269,7 +269,7 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
<simpara>Technical remark - Fraud Detection will have artifact id <literal>http-server</literal>, Loan Issuance <literal>http-client</literal> and both have group id <literal>com.example</literal>.</simpara>
|
||||
<simpara>Social remark - both client and server development teams need to communicate directly and discuss changes while
|
||||
going through the process. CDC is all about communication.</simpara>
|
||||
<simpara>The <link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/dsl/http-server">server side code is available here</link> and <link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/dsl/http-client">the client side code here</link>.</simpara>
|
||||
<simpara>The <link xl:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/dsl/http-server">server side code is available here</link> and <link xl:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/dsl/http-client">the client side code here</link>.</simpara>
|
||||
<tip>
|
||||
<simpara>In this case the ownership of the contracts lays on the producer side. It means that physically
|
||||
all the contract are present in the producer’s repository</simpara>
|
||||
@@ -444,11 +444,11 @@ define parts of a JSON / URL / etc. which are dynamic. In case of an identifier
|
||||
don’t want to hardcode a value. You want to allow some different ranges of values. That’s why for
|
||||
the consumer side you can set regular expressions matching those values. You can provide the body
|
||||
either by means of a map notation or String with interpolations.
|
||||
<link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_contract_dsl">Consult the docs
|
||||
<link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_contract_dsl">Consult the docs
|
||||
for more information.</link> We highly recommend using the map notation!</simpara>
|
||||
<tip>
|
||||
<simpara>It’s really important that you understand the map notation to set up contracts. Please read the
|
||||
<link xlink:href="http://groovy-lang.org/json.html">Groovy docs regarding JSON</link></simpara>
|
||||
<link xl:href="http://groovy-lang.org/json.html">Groovy docs regarding JSON</link></simpara>
|
||||
</tip>
|
||||
<simpara>The aforementioned contract is an agreement between two sides that:</simpara>
|
||||
<itemizedlist>
|
||||
@@ -608,7 +608,7 @@ folder we’re picking only one which is <literal>fraud</literal>. We’
|
||||
That gives us the <literal>FraudBase</literal> test class name.</simpara>
|
||||
</important>
|
||||
<simpara>That’s because all the generated tests will extend that class. Over there you can set up your Spring Context or
|
||||
whatever is necessary. In our case we’re using <link xlink:href="http://rest-assured.io/">Rest Assured MVC</link> to start the server side <literal>FraudDetectionController</literal>.</simpara>
|
||||
whatever is necessary. In our case we’re using <link xl:href="http://rest-assured.io/">Rest Assured MVC</link> to start the server side <literal>FraudDetectionController</literal>.</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">package com.example.fraud;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -692,7 +692,9 @@ git merge --no-ff contract-change-pr</programlisting>
|
||||
<simpara>Now you can disable the offline work for Spring Cloud Contract Stub Runner and provide where the repository with your stubs is placed. At this moment the stubs of the server side will be automatically downloaded from Nexus / Artifactory.
|
||||
You can switch off the value of the <literal>workOffline</literal> parameter in your annotation. Below you can see an
|
||||
example of achieving the same by changing the properties.</simpara>
|
||||
<programlisting language="yaml" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud/spring-cloud-contract/2.0.x/samples/standalone/dsl/http-client/src/test/resources/application-test-repo.yaml[]</programlisting>
|
||||
<programlisting language="yaml" linenumbering="unnumbered">stubrunner:
|
||||
ids: 'com.example:http-server-dsl:+:stubs:8080'
|
||||
repositoryRoot: http://repo.spring.io/libs-snapshot</programlisting>
|
||||
<simpara>And that’s it!</simpara>
|
||||
</section>
|
||||
</section>
|
||||
@@ -715,23 +717,23 @@ is under constant development.</simpara>
|
||||
<title>Readings</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura">Slides from Marcin Grzejszczak’s talk about Accurest</link></simpara>
|
||||
<simpara><link xl:href="http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura">Slides from Marcin Grzejszczak’s talk about Accurest</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="http://toomuchcoding.com/blog/categories/accurest/">Accurest related articles from Marcin Grzejszczak’s blog</link></simpara>
|
||||
<simpara><link xl:href="http://toomuchcoding.com/blog/categories/accurest/">Accurest related articles from Marcin Grzejszczak’s blog</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="http://toomuchcoding.com/blog/categories/spring-cloud-contract/">Spring Cloud Contract related articles from Marcin Grzejszczak’s blog</link></simpara>
|
||||
<simpara><link xl:href="http://toomuchcoding.com/blog/categories/spring-cloud-contract/">Spring Cloud Contract related articles from Marcin Grzejszczak’s blog</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="http://groovy-lang.org/json.html">Groovy docs regarding JSON</link></simpara>
|
||||
<simpara><link xl:href="http://groovy-lang.org/json.html">Groovy docs regarding JSON</link></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="_samples">
|
||||
<title>Samples</title>
|
||||
<simpara>Here you can find some <link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples">samples</link>.</simpara>
|
||||
<simpara>Here you can find some <link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples">samples</link>.</simpara>
|
||||
</section>
|
||||
</section>
|
||||
<section xml:id="_faq">
|
||||
@@ -825,7 +827,7 @@ value(client(...), server(...))</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">$(consumer(...), producer(...))
|
||||
$(stub(...), test(...))
|
||||
$(client(...), server(...))</programlisting>
|
||||
<simpara>You can read more about this in the <link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_contract_dsl">Contract DSL section</link>.</simpara>
|
||||
<simpara>You can read more about this in the <link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_contract_dsl">Contract DSL section</link>.</simpara>
|
||||
<simpara>Calling <literal>value()</literal> or <literal>$()</literal> tells Spring Cloud Contract that you will be passing a dynamic value.
|
||||
Inside the <literal>consumer()</literal> method you pass the value that should be used on the consumer side (in the generated stub).
|
||||
Inside the <literal>producer()</literal> method you pass the value that should be used on the producer side (in the generated test).</simpara>
|
||||
@@ -856,7 +858,7 @@ for time and UUID are simplified and most likely invalid but we want to keep thi
|
||||
}
|
||||
}</programlisting>
|
||||
<important>
|
||||
<simpara>Please read the <link xlink:href="http://groovy-lang.org/json.html">Groovy docs related to JSON</link> to understand how to
|
||||
<simpara>Please read the <link xl:href="http://groovy-lang.org/json.html">Groovy docs related to JSON</link> to understand how to
|
||||
properly structure the request / response bodies.</simpara>
|
||||
</important>
|
||||
</section>
|
||||
@@ -917,7 +919,7 @@ consumer will you break with your local changes.</simpara>
|
||||
<title>Repo structure</title>
|
||||
<simpara>Let’s assume that we have a producer with coordinates <literal>com.example:server</literal> and 3 consumers: <literal>client1</literal>,
|
||||
<literal>client2</literal>, <literal>client3</literal>. Then in the repository with common contracts you would have the following setup
|
||||
(which you can checkout <link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/contracts">here</link>:</simpara>
|
||||
(which you can checkout <link xl:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples/standalone/contracts">here</link>:</simpara>
|
||||
<programlisting language="bash" linenumbering="unnumbered">├── com
|
||||
│ └── example
|
||||
│ └── server
|
||||
@@ -1128,7 +1130,7 @@ Those poms are necessary for the consumer side to run <literal>mvn clean install
|
||||
consumer team clones the common repository, goes to the required producer’s folder (e.g. <literal>com/example/server</literal>)
|
||||
and runs <literal>mvn clean install -DskipTests</literal> to install locally the stubs converted from the contracts.</simpara>
|
||||
<tip>
|
||||
<simpara>You need to have <link xlink:href="http://maven.apache.org/download.cgi">Maven installed locally</link></simpara>
|
||||
<simpara>You need to have <link xl:href="http://maven.apache.org/download.cgi">Maven installed locally</link></simpara>
|
||||
</tip>
|
||||
</section>
|
||||
<section xml:id="_producer">
|
||||
@@ -1147,7 +1149,7 @@ of the JAR containing the contracts:</simpara>
|
||||
</configuration>
|
||||
</plugin></programlisting>
|
||||
<simpara>With this setup the JAR with groupid <literal>com.example.standalone</literal> and artifactid <literal>contracts</literal> will be downloaded
|
||||
from <literal><link xlink:href="http://link/to/your/nexus/or/artifactory/or/sth">http://link/to/your/nexus/or/artifactory/or/sth</link></literal>. It will be then unpacked in a local temporary folder
|
||||
from <literal><link xl:href="http://link/to/your/nexus/or/artifactory/or/sth">http://link/to/your/nexus/or/artifactory/or/sth</link></literal>. It will be then unpacked in a local temporary folder
|
||||
and contracts present under the <literal>com/example/server</literal> will be picked as the ones used to generate the
|
||||
tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken
|
||||
when some incompatible changes are done.</simpara>
|
||||
@@ -1157,12 +1159,12 @@ when some incompatible changes are done.</simpara>
|
||||
</section>
|
||||
<section xml:id="_can_i_have_multiple_base_classes_for_tests">
|
||||
<title>Can I have multiple base classes for tests?</title>
|
||||
<simpara>Yes! Check out the <link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_different_base_classes_for_contracts">Different base classes for contracts</link> sections
|
||||
<simpara>Yes! Check out the <link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_different_base_classes_for_contracts">Different base classes for contracts</link> sections
|
||||
of either Gradle or Maven plugins.</simpara>
|
||||
</section>
|
||||
<section xml:id="_how_can_i_debug_the_request_response_being_sent_by_the_generated_tests_client">
|
||||
<title>How can I debug the request/response being sent by the generated tests client?</title>
|
||||
<simpara>The generated tests all boil down to RestAssured in some form or fashion which relies on <link xlink:href="https://hc.apache.org/httpcomponents-client-ga/">Apache HttpClient</link>. HttpClient has a facility called <link xlink:href="https://hc.apache.org/httpcomponents-client-ga/logging.html#Wire_Logging">wire logging</link> which logs the entire request and response to HttpClient. Spring Boot has a logging <link xlink:href="https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html">common application property</link> for doing this sort of thing, just add this to your application properties</simpara>
|
||||
<simpara>The generated tests all boil down to RestAssured in some form or fashion which relies on <link xl:href="https://hc.apache.org/httpcomponents-client-ga/">Apache HttpClient</link>. HttpClient has a facility called <link xl:href="https://hc.apache.org/httpcomponents-client-ga/logging.html#Wire_Logging">wire logging</link> which logs the entire request and response to HttpClient. Spring Boot has a logging <link xl:href="https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html">common application property</link> for doing this sort of thing, just add this to your application properties</simpara>
|
||||
<programlisting language="properties" linenumbering="unnumbered">logging.level.org.apache.http.wire=DEBUG</programlisting>
|
||||
</section>
|
||||
<section xml:id="_how_can_i_debug_the_mapping_request_response_being_sent_by_wiremock">
|
||||
@@ -1200,7 +1202,7 @@ DSL and provide a path relative to where the contract lays.</simpara>
|
||||
<simpara>In order to use Spring Cloud Contract Verifier with WireMock you have to use Gradle or Maven plugin.</simpara>
|
||||
<warning>
|
||||
<simpara>If you want to use Spock in your projects you have to add separately
|
||||
the <literal>spock-core</literal> and <literal>spock-spring</literal> modules. Check <link xlink:href="http://spockframework.github.io/">Spock docs for more information</link></simpara>
|
||||
the <literal>spock-core</literal> and <literal>spock-spring</literal> modules. Check <link xl:href="http://spockframework.github.io/">Spock docs for more information</link></simpara>
|
||||
</warning>
|
||||
<section xml:id="_add_gradle_plugin_with_dependencies">
|
||||
<title>Add gradle plugin with dependencies</title>
|
||||
@@ -1521,7 +1523,7 @@ class LoanApplicationServiceSpec extends Specification {
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
</configuration>
|
||||
</plugin></programlisting>
|
||||
<simpara>You can read more in the <link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/">Spring Cloud Contract Maven Plugin Docs</link></simpara>
|
||||
<simpara>You can read more in the <link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/">Spring Cloud Contract Maven Plugin Docs</link></simpara>
|
||||
<section xml:id="_maven_and_rest_assured_2_0">
|
||||
<title>Maven and Rest Assured 2.0</title>
|
||||
<simpara>By default Rest Assured 3.x is added to the classpath. However in order to give the users the
|
||||
@@ -1966,7 +1968,7 @@ a WireMock server configured using stubs generated by Spring Cloud Contract Veri
|
||||
<simpara>logout marked as <literal>Step2</literal> which will close the scenario.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>More details about WireMock scenarios can be found under <link xlink:href="http://wiremock.org/stateful-behaviour.html">http://wiremock.org/stateful-behaviour.html</link></simpara>
|
||||
<simpara>More details about WireMock scenarios can be found under <link xl:href="http://wiremock.org/stateful-behaviour.html">http://wiremock.org/stateful-behaviour.html</link></simpara>
|
||||
<simpara>Spring Cloud Contract Verifier will also generate tests with guaranteed order of execution.</simpara>
|
||||
</section>
|
||||
<section xml:id="_stubs_and_transitive_dependencies">
|
||||
@@ -2402,13 +2404,71 @@ automatically for you.</simpara>
|
||||
<title>Maven</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered"><!-- First disable the default jar setup in the properties section-->
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/pom.xml[]
|
||||
<!-- we don't want the verifier to do a jar for us -->
|
||||
<spring.cloud.contract.verifier.skip>true</spring.cloud.contract.verifier.skip>
|
||||
|
||||
<!-- Next add the assembly plugin to your build -->
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/pom.xml[]
|
||||
<!-- we want the assembly plugin to generate the JAR -->
|
||||
<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>
|
||||
<descriptor>${basedir}/src/assembly/stub.xml</descriptor>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Finally setup your assembly. Below you can find the contents of src/main/assembly/stub.xml -->
|
||||
link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer_with_restdocs/src/assembly/stub.xml[]</programlisting>
|
||||
<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>src/main/java</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>**com/example/model/*.*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/classes</directory>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<includes>
|
||||
<include>**com/example/model/*.*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.build.directory}/snippets/stubs</directory>
|
||||
<outputDirectory>META-INF/${project.groupId}/${project.artifactId}/${project.version}/mappings</outputDirectory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<directory>${basedir}/src/test/resources/contracts</directory>
|
||||
<outputDirectory>META-INF/${project.groupId}/${project.artifactId}/${project.version}/contracts</outputDirectory>
|
||||
<includes>
|
||||
<include>**/*.groovy</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly></programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<formalpara role="secondary">
|
||||
@@ -2439,7 +2499,7 @@ publishing {
|
||||
<section xml:id="_stub_runner_core">
|
||||
<title>Stub Runner Core</title>
|
||||
<simpara>Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of
|
||||
<link xlink:href="http://martinfowler.com/articles/consumerDrivenContracts.html">Consumer Driven Contracts</link>.</simpara>
|
||||
<link xl:href="http://martinfowler.com/articles/consumerDrivenContracts.html">Consumer Driven Contracts</link>.</simpara>
|
||||
<simpara>Stub Runner allows you to automatically download the stubs of the provided dependencies (or pick those from the classpath), start WireMock servers for them and feed them with proper stub definitions.
|
||||
For messaging, special stub routes are defined.</simpara>
|
||||
<section xml:id="_retrieving_stubs">
|
||||
@@ -2556,8 +2616,8 @@ producer stubs.</simpara>
|
||||
└── nested
|
||||
└── contract3.groovy</programlisting>
|
||||
<simpara>To achieve proper stub packaging.</simpara>
|
||||
<simpara>Or using the <link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_with_restdocs/pom.xml">Maven <literal>assembly</literal> plugin</link> or
|
||||
<link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_with_restdocs/build.gradle">Gradle Jar</link> task you have to create the following
|
||||
<simpara>Or using the <link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_with_restdocs/pom.xml">Maven <literal>assembly</literal> plugin</link> or
|
||||
<link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_with_restdocs/build.gradle">Gradle Jar</link> task you have to create the following
|
||||
structure in your stubs jar.</simpara>
|
||||
<programlisting language="bash" linenumbering="unnumbered">└── META-INF
|
||||
└── com.example
|
||||
@@ -2619,7 +2679,7 @@ HTTP stubs without the need to download artifacts.</simpara>
|
||||
</section>
|
||||
<section xml:id="_http_stubs">
|
||||
<title>HTTP Stubs</title>
|
||||
<simpara>Stubs are defined in JSON documents, whose syntax is defined in <link xlink:href="http://wiremock.org/stubbing.html">WireMock documentation</link></simpara>
|
||||
<simpara>Stubs are defined in JSON documents, whose syntax is defined in <link xl:href="http://wiremock.org/stubbing.html">WireMock documentation</link></simpara>
|
||||
<simpara>Example:</simpara>
|
||||
<programlisting language="javascript" linenumbering="unnumbered">{
|
||||
"request": {
|
||||
@@ -2704,8 +2764,8 @@ mappings available for the given server:</simpara>
|
||||
<simpara>can also send messages (remember to pass an implementation of <literal>MessageVerifier</literal> interface)</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Stub Runner uses <link xlink:href="https://wiki.eclipse.org/Aether">Eclipse Aether</link> mechanism to download the Maven dependencies.
|
||||
Check their <link xlink:href="https://wiki.eclipse.org/Aether">docs</link> for more information.</simpara>
|
||||
<simpara>Stub Runner uses <link xl:href="https://wiki.eclipse.org/Aether">Eclipse Aether</link> mechanism to download the Maven dependencies.
|
||||
Check their <link xl:href="https://wiki.eclipse.org/Aether">docs</link> for more information.</simpara>
|
||||
<simpara>Since the <literal>StubRunnerRule</literal> implements the <literal>StubFinder</literal> it allows you to find the started stubs:</simpara>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">package org.springframework.cloud.contract.stubrunner;
|
||||
|
||||
@@ -2943,10 +3003,10 @@ for every registered WireMock server. Example for Stub Runner ids
|
||||
<simpara>For real life examples you can check the</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/producer">producer app sample</link></simpara>
|
||||
<simpara><link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/producer">producer app sample</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/consumer_with_discovery">consumer app sample</link></simpara>
|
||||
<simpara><link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/consumer_with_discovery">consumer app sample</link></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<section xml:id="_stubbing_service_discovery">
|
||||
@@ -2987,7 +3047,7 @@ stubrunner:
|
||||
<simpara>In your integration tests you typically don’t want to call neither a discovery service (e.g. Eureka)
|
||||
or Config Server. That’s why you create an additional test configuration in which you want to disable
|
||||
these features.</simpara>
|
||||
<simpara>Due to certain limitations of <link xlink:href="https://github.com/spring-cloud/spring-cloud-commons/issues/156"><literal>spring-cloud-commons</literal></link> to achieve this you have disable these properties
|
||||
<simpara>Due to certain limitations of <link xl:href="https://github.com/spring-cloud/spring-cloud-commons/issues/156"><literal>spring-cloud-commons</literal></link> to achieve this you have disable these properties
|
||||
via a static block like presented below (example for Eureka)</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered"> //Hack to work around https://github.com/spring-cloud/spring-cloud-commons/issues/156
|
||||
static {
|
||||
@@ -3014,7 +3074,7 @@ an existing <literal>DiscoveryClient</literal> its results will be ignored. Howe
|
||||
<simpara>Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to
|
||||
trigger the messaging labels and to access started WireMock servers.</simpara>
|
||||
<simpara>One of the use-cases is to run some smoke (end to end) tests on a deployed application.
|
||||
You can check out the <link xlink:href="https://github.com/spring-cloud/spring-cloud-pipelines">Spring Cloud Pipelines</link>
|
||||
You can check out the <link xl:href="https://github.com/spring-cloud/spring-cloud-pipelines">Spring Cloud Pipelines</link>
|
||||
project for more information.</simpara>
|
||||
<section xml:id="_how_to_use_it">
|
||||
<title>How to use it?</title>
|
||||
@@ -3027,7 +3087,7 @@ project for more information.</simpara>
|
||||
</section>
|
||||
<section xml:id="_spring_cloud_cli">
|
||||
<title>Spring Cloud CLI</title>
|
||||
<simpara>Starting from <literal>1.4.0.RELEASE</literal> version of the <link xlink:href="http://cloud.spring.io/spring-cloud-cli">Spring Cloud CLI</link>
|
||||
<simpara>Starting from <literal>1.4.0.RELEASE</literal> version of the <link xl:href="http://cloud.spring.io/spring-cloud-cli">Spring Cloud CLI</link>
|
||||
project you can start Stub Runner Boot by executing <literal>spring cloud stubrunner</literal>.</simpara>
|
||||
<simpara>In order to pass the configuration just create a <literal>stubrunner.yml</literal> file in the current working directory
|
||||
or a subdirectory called <literal>config</literal> or in <literal>~/.spring-cloud</literal>. The file could look like this
|
||||
@@ -3281,7 +3341,7 @@ class StubRunnerStubsPerConsumerWithConsumerNameSpec extends Specification {
|
||||
}</programlisting>
|
||||
<simpara>Then only the stubs registered under a path that contains the <literal>foo-consumer</literal> in its name (i.e. those from the
|
||||
<literal>src/test/resources/contracts/foo-consumer/some/contracts/…​</literal> folder) will be allowed to be referenced.</simpara>
|
||||
<simpara>You can check out <link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/issues/224">issue 224</link> for more
|
||||
<simpara>You can check out <link xl:href="https://github.com/spring-cloud/spring-cloud-contract/issues/224">issue 224</link> for more
|
||||
information about the reasons behind this change.</simpara>
|
||||
</section>
|
||||
<section xml:id="_common">
|
||||
@@ -3291,9 +3351,9 @@ information about the reasons behind this change.</simpara>
|
||||
<simpara>Some of the properties that are repetitive can be set using system properties or configuration properties (for Spring). Here are their names with their default values:</simpara>
|
||||
<informaltable frame="topbot" rowsep="1" colsep="1">
|
||||
<tgroup cols="3">
|
||||
<colspec colname="col_1" colwidth="33*"/>
|
||||
<colspec colname="col_2" colwidth="33*"/>
|
||||
<colspec colname="col_3" colwidth="33*"/>
|
||||
<colspec colname="col_1" colwidth="33.3333*"/>
|
||||
<colspec colname="col_2" colwidth="33.3333*"/>
|
||||
<colspec colname="col_3" colwidth="33.3334*"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry align="left" valign="top">Property name</entry>
|
||||
@@ -3374,9 +3434,9 @@ information about the reasons behind this change.</simpara>
|
||||
<simpara>Where <literal>port</literal> means the port of the WireMock server.</simpara>
|
||||
<important>
|
||||
<simpara>Starting from version 1.0.4 as a version you can provide a range of versions that you would like
|
||||
the Stub Runner to take into consideration. You can read more about the <link xlink:href="https://wiki.eclipse.org/Aether/New_and_Noteworthy#Version_Ranges">Aether versioning ranges here</link>.</simpara>
|
||||
the Stub Runner to take into consideration. You can read more about the <link xl:href="https://wiki.eclipse.org/Aether/New_and_Noteworthy#Version_Ranges">Aether versioning ranges here</link>.</simpara>
|
||||
</important>
|
||||
<simpara>Taken from <link xlink:href="http://download.eclipse.org/aether/aether-core/0.9.0/apidocs/org/eclipse/aether/util/version/GenericVersionScheme.html">Aether Docs</link>:</simpara>
|
||||
<simpara>Taken from <link xl:href="http://download.eclipse.org/aether/aether-core/0.9.0/apidocs/org/eclipse/aether/util/version/GenericVersionScheme.html">Aether Docs</link>:</simpara>
|
||||
<blockquote>
|
||||
<simpara>This scheme accepts versions of any form, interpreting a version as a sequence of numeric and alphabetic segments. The characters '-', '_', and '.' as well as the mere
|
||||
transitions from digit to letter and vice versa delimit the version segments. Delimiters are treated as equivalent.</simpara>
|
||||
@@ -4822,7 +4882,7 @@ find an object in the request body.</simpara>
|
||||
</section>
|
||||
<section xml:id="_dynamic_properties_in_matchers_sections">
|
||||
<title>Dynamic properties in matchers sections</title>
|
||||
<simpara>If you’ve been working with <link xlink:href="https://docs.pact.io/">Pact</link> this might seem familiar. Quite a few users
|
||||
<simpara>If you’ve been working with <link xl:href="https://docs.pact.io/">Pact</link> this might seem familiar. Quite a few users
|
||||
are used to having a separation between the body and setting dynamic parts of your contract.</simpara>
|
||||
<simpara>That’s why you can profit from two separate sections. One is called <literal>stubMatchers</literal> where you can
|
||||
define the dynamic values that should end up in a stub. You can set it in the <literal>request</literal> or <literal>inputMessage</literal>
|
||||
@@ -5494,16 +5554,147 @@ of:</simpara>
|
||||
<simpara>referencing of these classes in the DSLs</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>The full example can be found <link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples">here</link>.</simpara>
|
||||
<simpara>The full example can be found <link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples">here</link>.</simpara>
|
||||
<section xml:id="_common_jar">
|
||||
<title>Common JAR</title>
|
||||
<simpara>Below you can find three classes that we will reuse in the DSLs.</simpara>
|
||||
<simpara><emphasis role="strong">PatternUtils</emphasis> contains functions used by both the <emphasis role="strong">consumer</emphasis> and the <emphasis role="strong">producer</emphasis>.</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/PatternUtils.java[]</programlisting>
|
||||
<programlisting language="java" linenumbering="unnumbered">package com.example;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* If you want to use {@link Pattern} directly in your tests
|
||||
* then you can create a class resembling this one. It can
|
||||
* contain all the {@link Pattern} you want to use in the DSL.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* request {
|
||||
* body(
|
||||
* [ age: $(c(PatternUtils.oldEnough()))]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Notice that we're using both {@code $()} for dynamic values
|
||||
* and {@code c()} for the consumer side.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
//tag::impl[]
|
||||
public class PatternUtils {
|
||||
|
||||
public static String tooYoung() {
|
||||
//remove::start[]
|
||||
return "[0-1][0-9]";
|
||||
//remove::end[return]
|
||||
}
|
||||
|
||||
public static Pattern oldEnough() {
|
||||
//remove::start[]
|
||||
return Pattern.compile("[2-9][0-9]");
|
||||
//remove::end[return]
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes little sense but it's just an example ;)
|
||||
*/
|
||||
public static Pattern ok() {
|
||||
//remove::start[]
|
||||
return Pattern.compile("OK");
|
||||
//remove::end[return]
|
||||
}
|
||||
}
|
||||
//end::impl[]</programlisting>
|
||||
<simpara><emphasis role="strong">ConsumerUtils</emphasis> contains functions used by the <emphasis role="strong">consumer</emphasis>.</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/ConsumerUtils.java[]</programlisting>
|
||||
<programlisting language="java" linenumbering="unnumbered">package com.example;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.ClientDslProperty;
|
||||
|
||||
/**
|
||||
* DSL Properties passed to the DSL from the consumer's perspective.
|
||||
* That means that on the input side {@code Request} for HTTP
|
||||
* or {@code Input} for messaging you can have a regular expression.
|
||||
* On the {@code Response} for HTTP or {@code Output} for messaging
|
||||
* you have to have a concrete value.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
//tag::impl[]
|
||||
public class ConsumerUtils {
|
||||
/**
|
||||
* Consumer side property. By using the {@link ClientDslProperty}
|
||||
* you can omit most of boilerplate code from the perspective
|
||||
* of dynamic values. Example
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* request {
|
||||
* body(
|
||||
* [ age: $(ConsumerUtils.oldEnough())]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* That way it's in the implementation that we decide what value we will pass to the consumer
|
||||
* and which one to the producer.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public static ClientDslProperty oldEnough() {
|
||||
//remove::start[]
|
||||
// this example is not the best one and
|
||||
// theoretically you could just pass the regex instead of `ServerDslProperty` but
|
||||
// it's just to show some new tricks :)
|
||||
return new ClientDslProperty(PatternUtils.oldEnough(), 40);
|
||||
//remove::end[return]
|
||||
}
|
||||
|
||||
}
|
||||
//end::impl[]</programlisting>
|
||||
<simpara><emphasis role="strong">ProducerUtils</emphasis> contains functions used by the <emphasis role="strong">producer</emphasis>.</simpara>
|
||||
<programlisting language="java" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/common/src/main/java/com/example/ProducerUtils.java[]</programlisting>
|
||||
<programlisting language="java" linenumbering="unnumbered">package com.example;
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.ServerDslProperty;
|
||||
|
||||
/**
|
||||
* DSL Properties passed to the DSL from the producer's perspective.
|
||||
* That means that on the input side {@code Request} for HTTP
|
||||
* or {@code Input} for messaging you have to have a concrete value.
|
||||
* On the {@code Response} for HTTP or {@code Output} for messaging
|
||||
* you can have a regular expression.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
//tag::impl[]
|
||||
public class ProducerUtils {
|
||||
|
||||
/**
|
||||
* Producer side property. By using the {@link ProducerUtils}
|
||||
* you can omit most of boilerplate code from the perspective
|
||||
* of dynamic values. Example
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* response {
|
||||
* body(
|
||||
* [ status: $(ProducerUtils.ok())]
|
||||
* )
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* That way it's in the implementation that we decide what value we will pass to the consumer
|
||||
* and which one to the producer.
|
||||
*/
|
||||
public static ServerDslProperty ok() {
|
||||
// this example is not the best one and
|
||||
// theoretically you could just pass the regex instead of `ServerDslProperty` but
|
||||
// it's just to show some new tricks :)
|
||||
return new ServerDslProperty( PatternUtils.ok(), "OK");
|
||||
}
|
||||
}
|
||||
//end::impl[]</programlisting>
|
||||
</section>
|
||||
<section xml:id="_adding_the_dependency_to_project">
|
||||
<title>Adding the dependency to project</title>
|
||||
@@ -5517,13 +5708,18 @@ common jar classes will be visible in your Groovy files.</simpara>
|
||||
<formalpara role="primary">
|
||||
<title>Maven</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/pom.xml[]</programlisting>
|
||||
<programlisting language="xml" linenumbering="unnumbered"><dependency>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>beer-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency></programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<formalpara role="secondary">
|
||||
<title>Gradle</title>
|
||||
<para>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/build.gradle[]</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">testCompile("com.example:beer-common:0.0.1-SNAPSHOT")</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
</section>
|
||||
@@ -5533,20 +5729,83 @@ common jar classes will be visible in your Groovy files.</simpara>
|
||||
<formalpara role="primary">
|
||||
<title>Maven</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/pom.xml[]</programlisting>
|
||||
<programlisting language="xml" linenumbering="unnumbered"><plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>com.example</packageWithBaseClasses>
|
||||
<baseClassMappings>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*intoxication.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.intoxication.BeerIntoxicationBase</baseClassFQN>
|
||||
</baseClassMapping>
|
||||
</baseClassMappings>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>beer-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin></programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<formalpara role="secondary">
|
||||
<title>Gradle</title>
|
||||
<para>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/build.gradle[]</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">classpath "com.example:beer-common:0.0.1-SNAPSHOT"</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
</section>
|
||||
<section xml:id="_referencing_classes_in_dsls">
|
||||
<title>Referencing classes in DSLs</title>
|
||||
<simpara>Now you can reference your classes in your DSL. Example:</simpara>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">link:https://raw.githubusercontent.com/spring-cloud-samples/spring-cloud-contract-samples/master/producer/src/test/resources/contracts/beer/rest/shouldGrantABeerIfOldEnough.groovy[]</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">package contracts.beer.rest
|
||||
|
||||
import com.example.ConsumerUtils
|
||||
import com.example.ProducerUtils
|
||||
import org.springframework.cloud.contract.spec.Contract
|
||||
|
||||
Contract.make {
|
||||
description("""
|
||||
Represents a successful scenario of getting a beer
|
||||
|
||||
```
|
||||
given:
|
||||
client is old enough
|
||||
when:
|
||||
he applies for a beer
|
||||
then:
|
||||
we'll grant him the beer
|
||||
```
|
||||
|
||||
""")
|
||||
request {
|
||||
method 'POST'
|
||||
url '/check'
|
||||
body(
|
||||
age: $(ConsumerUtils.oldEnough())
|
||||
)
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body("""
|
||||
{
|
||||
"status": "${value(ProducerUtils.ok())}"
|
||||
}
|
||||
""")
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
@@ -5701,7 +5960,7 @@ class YamlContractConverter implements ContractConverter<List<YamlContract
|
||||
}</programlisting>
|
||||
<section xml:id="_pact_converter">
|
||||
<title>Pact converter</title>
|
||||
<simpara>Spring Cloud Contract comes with an out of the box support for <link xlink:href="https://docs.pact.io/">Pact</link> representation of contracts.
|
||||
<simpara>Spring Cloud Contract comes with an out of the box support for <link xl:href="https://docs.pact.io/">Pact</link> representation of contracts.
|
||||
In other words instead of using the Groovy DSL you can use Pact files. In this section
|
||||
we will present how to add such a support for your project.</simpara>
|
||||
<section xml:id="_pact_contract">
|
||||
@@ -5978,7 +6237,7 @@ DSL as input you can e.g. produce WireMock stubs and Pact files too!</simpara>
|
||||
<title>Custom Stub Runner</title>
|
||||
<simpara>If you decide to have a custom stub generation you also need a custom way of running
|
||||
stubs with your different stub provider.</simpara>
|
||||
<simpara>Let us assume that you’re using <link xlink:href="https://github.com/dreamhead/moco">Moco</link> to build your stubs.
|
||||
<simpara>Let us assume that you’re using <link xl:href="https://github.com/dreamhead/moco">Moco</link> to build your stubs.
|
||||
You wrote a proper stub generator and your stubs got placed in a JAR file.</simpara>
|
||||
<simpara>In order for Stub Runner to know how to run your stubs you have to define a custom
|
||||
HTTP Stub server implementation. It can look like this:</simpara>
|
||||
@@ -6112,31 +6371,31 @@ com.example.CustomStubDownloaderBuilder</screen>
|
||||
<simpara>Here you can find interesting links related to Spring Cloud Contract Verifier:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/">Spring Cloud Contract Github Repository</link></simpara>
|
||||
<simpara><link xl:href="https://github.com/spring-cloud/spring-cloud-contract/">Spring Cloud Contract Github Repository</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/">Spring Cloud Contract Samples</link></simpara>
|
||||
<simpara><link xl:href="https://github.com/spring-cloud-samples/spring-cloud-contract-samples/">Spring Cloud Contract Samples</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html">Spring Cloud Contract Documentation</link></simpara>
|
||||
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html">Spring Cloud Contract Documentation</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/deprecated">Accurest Legacy Documentation</link></simpara>
|
||||
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/deprecated">Accurest Legacy Documentation</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/#spring-cloud-contract-stub-runner">Spring Cloud Contract Stub Runner Documentation</link></simpara>
|
||||
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/#spring-cloud-contract-stub-runner">Spring Cloud Contract Stub Runner Documentation</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/#stub-runner-for-messaging">Spring Cloud Contract Stub Runner Messaging Documentation</link></simpara>
|
||||
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html/#stub-runner-for-messaging">Spring Cloud Contract Stub Runner Messaging Documentation</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://gitter.im/spring-cloud/spring-cloud-contract">Spring Cloud Contract Gitter</link></simpara>
|
||||
<simpara><link xl:href="https://gitter.im/spring-cloud/spring-cloud-contract">Spring Cloud Contract Gitter</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/">Spring Cloud Contract Maven Plugin</link></simpara>
|
||||
<simpara><link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract-maven-plugin/">Spring Cloud Contract Maven Plugin</link></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><link xlink:href="https://www.youtube.com/watch?v=sAAklvxmPmk">Spring Cloud Contract WJUG Presentation by Marcin Grzejszczak</link></simpara>
|
||||
<simpara><link xl:href="https://www.youtube.com/watch?v=sAAklvxmPmk">Spring Cloud Contract WJUG Presentation by Marcin Grzejszczak</link></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
@@ -6144,9 +6403,9 @@ com.example.CustomStubDownloaderBuilder</screen>
|
||||
<chapter xml:id="_spring_cloud_contract_wiremock">
|
||||
<title>Spring Cloud Contract WireMock</title>
|
||||
<simpara>Modules giving you the possibility to use
|
||||
<link xlink:href="http://wiremock.org">WireMock</link> with different servers by using the
|
||||
<link xl:href="http://wiremock.org">WireMock</link> with different servers by using the
|
||||
"ambient" server embedded in a Spring Boot application. Check out the
|
||||
<link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples">samples</link>
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-contract/tree/2.0.x/samples">samples</link>
|
||||
for more details.</simpara>
|
||||
<important>
|
||||
<simpara>The Spring Cloud Release Train BOM imports <literal>spring-cloud-contract-dependencies</literal>
|
||||
@@ -6322,7 +6581,7 @@ public class WiremockForDocsMockServerApplicationTests {
|
||||
method takes a stub path resource pattern as an argument. So in this
|
||||
example the stub defined at <literal>/stubs/resource.json</literal> is loaded into the
|
||||
mock server, so if the <literal>RestTemplate</literal> is asked to visit
|
||||
<literal><link xlink:href="http://example.org/">http://example.org/</link></literal> it will get the responses as declared
|
||||
<literal><link xl:href="http://example.org/">http://example.org/</link></literal> 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
|
||||
@@ -6336,7 +6595,7 @@ Spring Boot container if there is one.</simpara>
|
||||
</chapter>
|
||||
<chapter xml:id="_generating_stubs_using_restdocs">
|
||||
<title>Generating Stubs using RestDocs</title>
|
||||
<simpara><link xlink:href="https://projects.spring.io/spring-restdocs">Spring RestDocs</link> can be
|
||||
<simpara><link xl:href="https://projects.spring.io/spring-restdocs">Spring RestDocs</link> 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
|
||||
@@ -6393,7 +6652,7 @@ public class ApplicationTests {
|
||||
<simpara>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 <literal>.jsonPath()</literal> to add additional matchers. The
|
||||
<link xlink:href="https://github.com/jayway/JsonPath">JayWay documentation</link> can help you
|
||||
<link xl:href="https://github.com/jayway/JsonPath">JayWay documentation</link> can help you
|
||||
to get up to speed with JSON Path if it is unfamiliar to you.</simpara>
|
||||
<simpara>Instead of the <literal>jsonPath</literal> and <literal>contentType</literal> convenience methods, you
|
||||
can also use the WireMock APIs to verify the request matches the
|
||||
@@ -6440,7 +6699,7 @@ will generate a stub something like this:</simpara>
|
||||
and <literal>contentType()</literal> methods to create request matchers, but not both.</simpara>
|
||||
</note>
|
||||
<simpara>On the consumer side, you can make the <literal>resource.json</literal> generated above
|
||||
available on the classpath (by <link xlink:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_publishing_stubs_as_jars">publishing stubs as JARs</link> for example).
|
||||
available on the classpath (by <link xl:href="https://cloud.spring.io/spring-cloud-contract/spring-cloud-contract.html#_publishing_stubs_as_jars">publishing stubs as JARs</link> for example).
|
||||
After that, you can create a stub using WireMock in a
|
||||
number of different ways, including as described above using
|
||||
<literal>@AutoConfigureWireMock(stubs="classpath:resource.json")</literal>.</simpara>
|
||||
@@ -6615,7 +6874,7 @@ snippet above.</simpara>
|
||||
<literal>HttpServerStub</literal>, if you wrote a custom <literal>HttpServerStub</literal> implementation, you’ll
|
||||
have to implement that method too. It should return a <literal>String</literal> representing
|
||||
all mappings available in a single <literal>HttpServerStub</literal>. Related to
|
||||
<link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/issues/355">issue 355</link>.</simpara>
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-contract/issues/355">issue 355</link>.</simpara>
|
||||
</section>
|
||||
<section xml:id="_new_packages_for_generated_tests">
|
||||
<title>New packages for generated tests</title>
|
||||
@@ -6635,7 +6894,7 @@ all mappings available in a single <literal>HttpServerStub</literal>. Related to
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Related to
|
||||
<link xlink:href="https://github.com/spring-cloud/spring-cloud-contract/issues/260">issue 260</link>.</simpara>
|
||||
<link xl:href="https://github.com/spring-cloud/spring-cloud-contract/issues/260">issue 260</link>.</simpara>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user