Merge branch '2.1.x'

This commit is contained in:
Marcin Grzejszczak
2019-11-05 14:54:52 +01:00
18 changed files with 159 additions and 50 deletions

View File

@@ -290,7 +290,7 @@ public class ApplicationTests {
.content("{\"id\":\"123456\",\"message\":\"Hello World\"}"))
.andExpect(status().isOk())
.andDo(verify().jsonPath("$.id")
.stub("resource"));
.andDo(document("resource"));
}
}
----
@@ -317,7 +317,7 @@ following example shows:
.wiremock(WireMock.post(
urlPathEquals("/resource"))
.withRequestBody(matchingJsonPath("$.id"))
.stub("post-resource"));
.andDo(document("post-resource"));
}
----

View File

@@ -22,6 +22,15 @@
<include>**/model/Fraud*.*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/generated-snippets/stubs</directory>
<outputDirectory>
META-INF/${project.groupId}/${project.artifactId}/${project.version}/mappings
</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/snippets/stubs</directory>
<outputDirectory>

View File

@@ -36,6 +36,7 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import static org.springframework.cloud.contract.wiremock.restdocs.WireMockRestDocs.verify;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@RunWith(SpringRunner.class)
@@ -69,8 +70,8 @@ public class StubGeneratorTests {
.andExpect(jsonPath("$.rejectionReason").value("Amount too high"))
.andDo(verify().jsonPath("$.clientId")
.jsonPath("$[?(@.loanAmount > 1000)]")
.contentType(MediaType.valueOf("application/vnd.fraud.v1+json"))
.stub("markClientAsFraud"));
.contentType(MediaType.valueOf("application/vnd.fraud.v1+json")))
.andDo(document("markClientAsFraud"));
}
@Test
@@ -85,8 +86,8 @@ public class StubGeneratorTests {
.andExpect(jsonPath("$.rejectionReason").doesNotExist())
.andDo(verify().jsonPath("$.clientId")
.jsonPath("$[?(@.loanAmount <= 1000)]")
.contentType(MediaType.valueOf("application/vnd.fraud.v1+json"))
.stub("markClientAsNotFraud"));
.contentType(MediaType.valueOf("application/vnd.fraud.v1+json")))
.andDo(document("markClientAsNotFraud"));
}
}

View File

@@ -44,17 +44,33 @@ public final class HttpServerStubConfiguration {
*/
public final Integer port;
/**
* Is port a random one or was it fixed.
*/
public boolean randomPort;
public HttpServerStubConfiguration(HttpServerStubConfigurer configurer,
StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration,
Integer port) {
this(configurer, stubRunnerOptions, stubConfiguration, port, randomPort(port));
}
public HttpServerStubConfiguration(HttpServerStubConfigurer configurer,
StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration,
Integer port, boolean randomPort) {
this.configurer = configurer;
this.stubRunnerOptions = stubRunnerOptions;
this.stubConfiguration = stubConfiguration;
this.port = port;
this.randomPort = randomPort;
}
private static boolean randomPort(Integer port) {
return port == null || port == 0;
}
public boolean isRandomPort() {
return this.port == null || this.port == 0;
return randomPort(this.port);
}
public String toColonSeparatedDependencyNotation() {

View File

@@ -274,8 +274,9 @@ class StubRunnerExecutor implements StubFinder {
final List<File> mappings = repository.getStubs();
final Collection<Contract> contracts = repository.contracts;
Integer port = stubRunnerOptions.port(stubConfiguration);
boolean randomPort = randomPort(port);
HttpServerStubConfiguration configuration = new HttpServerStubConfiguration(
configurer, stubRunnerOptions, stubConfiguration, port);
configurer, stubRunnerOptions, stubConfiguration, port, randomPort);
if (!hasRequest(contracts) && mappings.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("There are no HTTP related contracts. Won't start any servers");
@@ -284,7 +285,7 @@ class StubRunnerExecutor implements StubFinder {
new NoOpHttpServerStub()).start(configuration);
return this.stubServer;
}
if (port != null && port >= 0) {
if (!randomPort) {
this.stubServer = new StubServer(stubConfiguration, mappings, contracts,
httpServerStub()).start(configuration);
}
@@ -297,7 +298,7 @@ class StubRunnerExecutor implements StubFinder {
httpServerStub()).start(
new HttpServerStubConfiguration(configurer,
stubRunnerOptions, stubConfiguration,
availablePort));
availablePort, true));
}
});
}
@@ -305,6 +306,10 @@ class StubRunnerExecutor implements StubFinder {
return this.stubServer;
}
private boolean randomPort(Integer port) {
return port == null || port == 0;
}
private boolean hasRequest(Collection<Contract> contracts) {
if (contracts.isEmpty()) {
return false;

View File

@@ -130,9 +130,9 @@ public class WireMockHttpServerStub implements HttpServerStub {
}
return this;
}
int port = SocketUtils.findAvailableTcpPort();
HttpServerStub serverStub = start(defaultConfiguration(port));
cacheStubServer(true, port);
HttpServerStubConfiguration configuration = defaultConfiguration();
HttpServerStub serverStub = start(configuration);
cacheStubServer(configuration.randomPort, configuration.port);
return serverStub;
}
@@ -142,6 +142,13 @@ public class WireMockHttpServerStub implements HttpServerStub {
null, port);
}
private HttpServerStubConfiguration defaultConfiguration() {
int port = SocketUtils.findAvailableTcpPort();
return new HttpServerStubConfiguration(
HttpServerStubConfigurer.NoOpHttpServerStubConfigurer.INSTANCE, null,
null, port, true);
}
@Override
public HttpServerStub start(int port) {
return start(defaultConfiguration(port));
@@ -175,7 +182,7 @@ public class WireMockHttpServerStub implements HttpServerStub {
+ " Started WireMock at [" + (this.https ? "https" : "http")
+ "] port [" + port + "]");
}
cacheStubServer(false, port);
cacheStubServer(configuration.randomPort, port);
return this;
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.stubrunner.provider.wiremock
class WireMockHttpServerStubAccessor {
static boolean everyPortRandom() {
assert WireMockHttpServerStub.SERVERS.every { it.value.random }
return true
}
}

View File

@@ -33,6 +33,7 @@ import org.springframework.boot.test.context.SpringBootTest
import org.springframework.cloud.contract.stubrunner.HttpServerStubConfiguration
import org.springframework.cloud.contract.stubrunner.StubFinder
import org.springframework.cloud.contract.stubrunner.StubNotFoundException
import org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStubAccessor
import org.springframework.cloud.contract.stubrunner.provider.wiremock.WireMockHttpServerStubConfigurer
import org.springframework.context.annotation.Configuration
import org.springframework.core.env.Environment
@@ -75,6 +76,11 @@ class StubRunnerConfigurationSpec extends Specification {
System.clearProperty("stubrunner.classifier")
}
def 'should mark all ports as random'() {
expect:
WireMockHttpServerStubAccessor.everyPortRandom()
}
def 'should start WireMock servers'() {
expect: 'WireMocks are running'
stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null

View File

@@ -748,7 +748,7 @@ class DslToWireMockClientConverterSpec extends Specification {
},
"response" : {
"status" : 200,
"body" : "{\\"date\\":\\"2017-01-01\\",\\"dateTime\\":\\"2017-01-01T01:23:45\\",\\"aBoolean\\":true,\\"valueWithMax\\":[1,2,3],\\"valueWithOccurrence\\":[1,2,3,4],\\"number\\":123,\\"duck\\":123,\\"alpha\\":\\"abc\\",\\"valueWithMin\\":[1,2,3],\\"time\\":\\"01:02:34\\",\\"valueWithTypeMatch\\":\\"string\\",\\"valueWithMinMax\\":[1,2,3],\\"valueWithoutAMatcher\\":\\"foo\\"}",
"body" : "{\\"duck\\":123,\\"alpha\\":\\"abc\\",\\"number\\":123,\\"aBoolean\\":true,\\"date\\":\\"2017-01-01\\",\\"dateTime\\":\\"2017-01-01T01:23:45\\",\\"time\\":\\"01:02:34\\",\\"valueWithoutAMatcher\\":\\"foo\\",\\"valueWithTypeMatch\\":\\"string\\",\\"valueWithMin\\":[1,2,3],\\"valueWithMax\\":[1,2,3],\\"valueWithMinMax\\":[1,2,3],\\"valueWithOccurrence\\":[1,2,3,4]}",
"headers" : {
"Content-Type" : "application/json"
},
@@ -987,7 +987,7 @@ class DslToWireMockClientConverterSpec extends Specification {
},
"response" : {
"status" : 400,
"body" : "{\\"reason\\":{\\"@type\\":\\"ErrorReason\\",\\"description\\":\\"Bad Request\\",\\"oid\\":\\"3.7\\",\\"httpCode\\":\\"400\\"},\\"subject\\":{\\"@type\\":\\"ErrorSubject\\",\\"description\\":\\"Profile\\",\\"oid\\":\\"8.2\\"},\\"message\\":\\"[8.2 Profile/3.7 Bad Request]\\"}",
"body" : "{\\"subject\\":{\\"@type\\":\\"ErrorSubject\\",\\"oid\\":\\"8.2\\",\\"description\\":\\"Profile\\"},\\"reason\\":{\\"@type\\":\\"ErrorReason\\",\\"oid\\":\\"3.7\\",\\"description\\":\\"Bad Request\\",\\"httpCode\\":\\"400\\"},\\"message\\":\\"[8.2 Profile/3.7 Bad Request]\\"}",
"headers" : {
"CorrelationID" : "11111111-1111-1111-1111-111111111111",
"Content-Type" : "application/json;charset=UTF-8"

View File

@@ -16,12 +16,11 @@
package org.springframework.cloud.contract.verifier.dsl.wiremock
import com.fasterxml.jackson.databind.ObjectMapper
import com.jayway.jsonpath.DocumentContext
import com.jayway.jsonpath.JsonPath
import groovy.json.JsonBuilder
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
import org.json.JSONObject
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.spec.ContractTemplate
@@ -38,7 +37,6 @@ import static org.springframework.cloud.contract.verifier.util.ContentType.UNKNO
import static org.springframework.cloud.contract.verifier.util.ContentUtils.extractValue
import static org.springframework.cloud.contract.verifier.util.ContentUtils.getClientContentType
import static org.springframework.cloud.contract.verifier.util.MapConverter.transformValues
/**
* Common abstraction over WireMock Request / Response conversion implementations
*
@@ -189,11 +187,10 @@ abstract class BaseWireMockStubStrategy {
Map convertedMap = MapConverter.transformValues(value) {
it instanceof GString ? it.toString() : it
} as Map
String jsonOutput = new JSONObject(new JsonBuilder(convertedMap).toString()).
toString()
String jsonOutput = new ObjectMapper().writeValueAsString(convertedMap)
return jsonOutput.replaceAll("\\\\\\\\\\\\", "\\\\")
}
return new JsonBuilder(value).toString()
return new ObjectMapper().writeValueAsString(value)
}
/**

View File

@@ -29,6 +29,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.cloud.contract.spec.Contract
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsEscapeHelper
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsJsonPathHelper
import org.springframework.cloud.contract.verifier.converter.YamlContractConverter
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.AssertionUtil
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
@@ -78,7 +79,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"surname\\":\\"Kowalsky\\",\\"created\\":\\"2014-02-02 12:23:43\\",\\"name\\":\\"Jan\\",\\"id\\":\\"123\\"}",
"body" : "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}",
"headers" : {
"Content-Type" : "application/json"
},
@@ -131,7 +132,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"ingredients\\":[{\\"quantity\\":100,\\"type\\":\\"MALT\\"},{\\"quantity\\":200,\\"type\\":\\"WATER\\"},{\\"quantity\\":300,\\"type\\":\\"HOP\\"},{\\"quantity\\":400,\\"type\\":\\"YIEST\\"}]}",
"body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}",
"transformers" : [ "response-template", "foo-transformer" ]
}
}
@@ -191,7 +192,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response": {
"status": 204,
"body": "{\\"foundExistingPayment\\":false,\\"paymentId\\":\\"4\\"}",
"body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}",
"transformers" : [ "response-template", "foo-transformer" ]
}
}
@@ -1968,7 +1969,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"number\\":0,\\"last\\":true,\\"numberOfElements\\":1,\\"size\\":1,\\"totalPages\\":1,\\"sort\\":[{\\"nullHandling\\":\\"NATIVE\\",\\"ignoreCase\\":false,\\"property\\":\\"id\\",\\"ascending\\":true,\\"direction\\":\\"ASC\\"}],\\"content\\":[{\\"id\\":\\"00000000-0000-0000-0000-000000000000\\",\\"state\\":\\"ACTIVE\\",\\"type\\":\\"Extraordinary\\"}],\\"first\\":true,\\"totalElements\\":1}",
"body" : "{\\"content\\":[{\\"id\\":\\"00000000-0000-0000-0000-000000000000\\",\\"type\\":\\"Extraordinary\\",\\"state\\":\\"ACTIVE\\"}],\\"totalPages\\":1,\\"totalElements\\":1,\\"last\\":true,\\"sort\\":[{\\"direction\\":\\"ASC\\",\\"property\\":\\"id\\",\\"ignoreCase\\":false,\\"nullHandling\\":\\"NATIVE\\",\\"ascending\\":true}],\\"first\\":true,\\"numberOfElements\\":1,\\"size\\":1,\\"number\\":0}",
"transformers" : [ "response-template", "foo-transformer" ]
}
}
@@ -2216,7 +2217,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"rawAuthorization2\\":\\"{{request.headers.Authorization.[1]}}\\",\\"responseBaz\\":{{{jsonPath request.body '$.baz'}}} ,\\"pathIndex\\":\\"{{{request.path.[1]}}}\\",\\"rawAuthorization\\":\\"{{request.headers.Authorization.[0]}}\\",\\"authorization2\\":\\"{{{request.headers.Authorization.[1]}}}\\",\\"rawParam\\":\\"{{request.query.foo.[0]}}\\",\\"url\\":\\"{{{request.url}}}\\",\\"paramIndex\\":\\"{{{request.query.foo.[1]}}}\\",\\"authorization\\":\\"{{{request.headers.Authorization.[0]}}}\\",\\"path\\":\\"{{{request.path}}}\\",\\"rawUrl\\":\\"{{request.url}}\\",\\"rawPath\\":\\"{{request.path}}\\",\\"rawResponseBaz2\\":\\"Bla bla {{jsonPath request.body '$.foo'}} bla bla\\",\\"param\\":\\"{{{request.query.foo.[0]}}}\\",\\"rawResponseBaz\\":{{jsonPath request.body '$.baz'}} ,\\"responseBaz2\\":\\"Bla bla {{{jsonPath request.body '$.foo'}}} bla bla\\",\\"rawResponseFoo\\":\\"{{jsonPath request.body '$.foo'}}\\",\\"responseFoo\\":\\"{{{jsonPath request.body '$.foo'}}}\\",\\"rawPathIndex\\":\\"{{request.path.[1]}}\\",\\"fullBody\\":\\"{{{escapejsonbody}}}\\",\\"rawParamIndex\\":\\"{{request.query.foo.[1]}}\\"}",
"body" : "{\\"url\\":\\"{{{request.url}}}\\",\\"path\\":\\"{{{request.path}}}\\",\\"pathIndex\\":\\"{{{request.path.[1]}}}\\",\\"param\\":\\"{{{request.query.foo.[0]}}}\\",\\"paramIndex\\":\\"{{{request.query.foo.[1]}}}\\",\\"authorization\\":\\"{{{request.headers.Authorization.[0]}}}\\",\\"authorization2\\":\\"{{{request.headers.Authorization.[1]}}}\\",\\"fullBody\\":\\"{{{escapejsonbody}}}\\",\\"responseFoo\\":\\"{{{jsonPath request.body '$.foo'}}}\\",\\"responseBaz\\":{{{jsonPath request.body '$.baz'}}} ,\\"responseBaz2\\":\\"Bla bla {{{jsonPath request.body '$.foo'}}} bla bla\\",\\"rawUrl\\":\\"{{request.url}}\\",\\"rawPath\\":\\"{{request.path}}\\",\\"rawPathIndex\\":\\"{{request.path.[1]}}\\",\\"rawParam\\":\\"{{request.query.foo.[0]}}\\",\\"rawParamIndex\\":\\"{{request.query.foo.[1]}}\\",\\"rawAuthorization\\":\\"{{request.headers.Authorization.[0]}}\\",\\"rawAuthorization2\\":\\"{{request.headers.Authorization.[1]}}\\",\\"rawResponseFoo\\":\\"{{jsonPath request.body '$.foo'}}\\",\\"rawResponseBaz\\":{{jsonPath request.body '$.baz'}} ,\\"rawResponseBaz2\\":\\"Bla bla {{jsonPath request.body '$.foo'}} bla bla\\"}",
"headers" : {
"Authorization" : "{{{request.headers.Authorization.[0]}}};foo"
},
@@ -2327,7 +2328,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"access_token\\":\\"RANDOM_ACCESS_TOKEN\\",\\"refresh_token\\":\\"RANDOM_REFRESH_TOKEN\\",\\"scope\\":[\\"task\\"],\\"token_type\\":\\"bearer\\",\\"expires_in\\":3600,\\"user\\":{\\"name\\":\\"User\\",\\"id\\":1,\\"username\\":\\"user\\"}}",
"body" : "{\\"refresh_token\\":\\"RANDOM_REFRESH_TOKEN\\",\\"access_token\\":\\"RANDOM_ACCESS_TOKEN\\",\\"token_type\\":\\"bearer\\",\\"expires_in\\":3600,\\"scope\\":[\\"task\\"],\\"user\\":{\\"id\\":1,\\"username\\":\\"user\\",\\"name\\":\\"User\\"}}",
"headers" : {
"Content-Type" : "application/json"
},
@@ -2570,7 +2571,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"code\\":91015,\\"payload\\":null,\\"description\\":\\"\\",\\"lastUpdateTime\\":\\"0\\"}",
"body" : "{\\"code\\":91015,\\"description\\":\\"\\",\\"lastUpdateTime\\":\\"0\\",\\"payload\\":null}",
"transformers" : [ "response-template", "foo-transformer" ]
}
}
@@ -2641,7 +2642,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
},
"response" : {
"status" : 200,
"body" : "{\\"access_token\\":\\"RANDOM_ACCESS_TOKEN\\",\\"refresh_token\\":\\"RANDOM_REFRESH_TOKEN\\",\\"scope\\":[\\"task\\"],\\"token_type\\":\\"bearer\\",\\"expires_in\\":3600,\\"user\\":{\\"name\\":\\"User\\",\\"id\\":1,\\"username\\":\\"user\\"}}",
"body" : "{\\"refresh_token\\":\\"RANDOM_REFRESH_TOKEN\\",\\"access_token\\":\\"RANDOM_ACCESS_TOKEN\\",\\"token_type\\":\\"bearer\\",\\"expires_in\\":3600,\\"scope\\":[\\"task\\"],\\"user\\":{\\"id\\":1,\\"username\\":\\"user\\",\\"name\\":\\"User\\"}}",
"headers" : {
"Content-Type" : "application/json;charset=UTF-8"
},
@@ -2844,6 +2845,23 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
}
@Issue("#1038")
def "should deal with unicode strings"() {
given:
File file = new File(WireMockGroovyDslSpec.getResource("/yml/issue1038.yml").
toURI())
Contract contractDsl = new YamlContractConverter().convertFrom(file).first()
when:
String wireMockStub = new WireMockStubStrategy("Test",
new ContractMetadata(null, false, 0, null, contractDsl), contractDsl)
.toWireMockClientStub()
then:
wireMockStub.contains('''\\"country\\":\\"日本\\"''')
stubMappingIsValidWireMockStub(wireMockStub)
}
WireMockConfiguration config() {
return new WireMockConfiguration().extensions(responseTemplateTransformer())
}

View File

@@ -0,0 +1,15 @@
name: get-all-users
request:
url: /users
method: GET
response:
status: 200
headers:
content-type: application/json; charset=UTF-8
body:
- id: 001
name: alice
country: US
- id: 002
name: bob
country: 日本

View File

@@ -47,8 +47,7 @@ import org.springframework.restdocs.snippet.Snippet;
* // first WireMock
* .andDo(WireMockRestDocs.verify()
* .jsonPath("$[?(&#64;.foo >= 20)]")
* .contentType(MediaType.valueOf("application/json"))
* .stub("shouldGrantABeerIfOldEnough"))
* .contentType(MediaType.valueOf("application/json")))
* // then Contract DSL documentation
* .andDo(document("index", SpringCloudContractRestDocs.dslContract()));
* }

View File

@@ -33,7 +33,8 @@ package org.springframework.cloud.contract.wiremock.restdocs;
* public void contextLoads() throws Exception {
* mockMvc.perform(get("/resource"))
* .andExpect(content().string("Hello World"))
* .andDo(verify().stub("resource"));
* .andDo(verify())
* .andDo(document("resource"));
* }
* </pre> which creates a file "target/snippets/stubs/resource.json" matching any GET
* request to "/resource". To match POST and PUT, you can also specify the content type

View File

@@ -42,20 +42,19 @@ public abstract class WireMockVerifyHelper<T, S extends WireMockVerifyHelper<T,
private MediaType contentType;
private String name;
private MappingBuilder builder;
/**
* @param name the stub name (ignored)
* @return this
* @deprecated in favour of explicitly calling <code>andDo(document(name))</code>
*/
@SuppressWarnings("unchecked")
@Deprecated
public S stub(String name) {
this.name = name;
return (S) this;
}
protected String getName() {
return this.name;
}
public void configure(T result) {
Map<String, Object> configuration = getConfiguration(result);
String actual = new String(getRequestBodyContent(result),

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.contract.wiremock;
import java.io.File;
import com.github.tomakehurst.wiremock.client.WireMock;
import org.junit.Rule;
import org.junit.Test;
@@ -34,12 +36,16 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@AutoConfigureRestDocs(outputDir = "target/snippets")
@@ -54,14 +60,16 @@ public class WiremockServerRestDocsMatcherApplicationTests {
@Test
public void matchesRequest() throws Exception {
FileSystemUtils.deleteRecursively(new File("target/snippets/stubs/posted.json"));
this.mockMvc
.perform(MockMvcRequestBuilders.post("/resource").content("greeting")
.contentType(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.content().string("Hello World"))
.andDo(WireMockRestDocs.verify()
.wiremock(WireMock.post(WireMock.urlPathEqualTo("/resource"))
.withRequestBody(WireMock.matching("greeting.*")))
.stub("posted"));
.withRequestBody(WireMock.matching("greeting.*"))))
.andDo(document("posted"));
assertThat(new File("target/snippets/stubs/posted.json")).exists();
}
@Test
@@ -74,8 +82,8 @@ public class WiremockServerRestDocsMatcherApplicationTests {
.andExpect(MockMvcResultMatchers.content().string("Hello World"))
.andDo(WireMockRestDocs.verify()
.wiremock(WireMock.post(WireMock.urlPathEqualTo("/resource"))
.withRequestBody(WireMock.matching("garbage.*")))
.stub("posted"));
.withRequestBody(WireMock.matching("garbage.*"))))
.andDo(document("posted"));
}
@Configuration

View File

@@ -77,7 +77,9 @@ public class ContractDslSnippetTests {
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation)).build();
.apply(documentationConfiguration(this.restDocumentation).snippets()
.withAdditionalDefaults(new WireMockSnippet()))
.build();
}
@Test
@@ -92,13 +94,13 @@ public class ContractDslSnippetTests {
// first WireMock
.andDo(WireMockRestDocs.verify().jsonPath("$[?(@.foo >= 20)]")
.jsonPath("$[?(@.bar in ['baz','bazz','bazzz'])]")
.contentType(MediaType.valueOf("application/json"))
.stub("shouldGrantABeerIfOldEnough"))
.contentType(MediaType.valueOf("application/json")))
// then Contract DSL documentation
.andDo(document("index", SpringCloudContractRestDocs.dslContract()));
// end::contract_snippet[]
then(file("/contracts/index.groovy")).exists();
then(file("/stubs/index.json")).exists();
then(file("/index/dsl-contract.adoc")).exists();
Collection<Contract> parsedContracts = ContractVerifierDslConverter
.convertAsCollection(new File("/"), file("/contracts/index.groovy"));
@@ -131,8 +133,7 @@ public class ContractDslSnippetTests {
// first WireMock
.andDo(WireMockRestDocs.verify().jsonPath("$[?(@.foo >= 20)]")
.jsonPath("$[?(@.bar in ['baz','bazz','bazzz'])]")
.contentType(MediaType.valueOf("application/json"))
.stub("shouldGrantABeerIfOldEnough"))
.contentType(MediaType.valueOf("application/json")))
// then Contract DSL documentation
.andDo(document("{methodName}",
SpringCloudContractRestDocs.dslContract()));
@@ -140,6 +141,9 @@ public class ContractDslSnippetTests {
then(file(
"/contracts/should_create_contract_template_and_doc_with_placeholder_names.groovy"))
.exists();
then(file(
"/stubs/should_create_contract_template_and_doc_with_placeholder_names.json"))
.exists();
then(file(
"/should_create_contract_template_and_doc_with_placeholder_names/dsl-contract.adoc"))
.exists();