From bcce5699dec3374cb4937e48c2149d82647fee05 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Jul 2016 09:32:21 +0100 Subject: [PATCH] Add additional build() step to allow ordered stubs --- ...mockForDocsMockServerApplicationTests.java | 3 +- .../WiremockMockServerApplicationTests.java | 2 +- .../WiremockMockServerApplicationTests.java | 2 +- .../WiremockMockServerApplicationTests.java | 2 +- .../wiremock/WireMockRestServiceServer.java | 84 ++++++++++++++++--- ...gureWireMockHttpsPortApplicationTests.java | 2 +- .../WiremockMockServerApplicationTests.java | 52 ++++++++---- .../src/test/resources/mappings/accept.json | 11 +++ .../src/test/resources/mappings/poster.json | 10 +++ 9 files changed, 133 insertions(+), 35 deletions(-) create mode 100644 spring-cloud-contract-wiremock/src/test/resources/mappings/accept.json create mode 100644 spring-cloud-contract-wiremock/src/test/resources/mappings/poster.json diff --git a/samples/wiremock-jetty/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java b/samples/wiremock-jetty/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java index da2dab926c..8bbcec20ff 100644 --- a/samples/wiremock-jetty/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java +++ b/samples/wiremock-jetty/src/test/java/com/example/WiremockForDocsMockServerApplicationTests.java @@ -29,7 +29,8 @@ public class WiremockForDocsMockServerApplicationTests { public void contextLoads() throws Exception { // will read stubs classpath MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) - .baseUrl("http://example.org").stubs("classpath:/stubs/resource.json"); + .baseUrl("http://example.org").stubs("classpath:/stubs/resource.json") + .build(); // We're asserting if WireMock responded properly assertThat(this.service.go()).isEqualTo("Hello World"); server.verify(); diff --git a/samples/wiremock-jetty/src/test/java/com/example/WiremockMockServerApplicationTests.java b/samples/wiremock-jetty/src/test/java/com/example/WiremockMockServerApplicationTests.java index 100876325e..6044625d39 100644 --- a/samples/wiremock-jetty/src/test/java/com/example/WiremockMockServerApplicationTests.java +++ b/samples/wiremock-jetty/src/test/java/com/example/WiremockMockServerApplicationTests.java @@ -28,7 +28,7 @@ public class WiremockMockServerApplicationTests { public void contextLoads() throws Exception { MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/stubs/resource.json"); + .stubs("classpath:/stubs/resource.json").build(); assertThat(this.service.go()).isEqualTo("Hello World"); server.verify(); } diff --git a/samples/wiremock-tomcat/src/test/java/com/example/WiremockMockServerApplicationTests.java b/samples/wiremock-tomcat/src/test/java/com/example/WiremockMockServerApplicationTests.java index 33f609b71b..bf75089652 100644 --- a/samples/wiremock-tomcat/src/test/java/com/example/WiremockMockServerApplicationTests.java +++ b/samples/wiremock-tomcat/src/test/java/com/example/WiremockMockServerApplicationTests.java @@ -28,7 +28,7 @@ public class WiremockMockServerApplicationTests { public void contextLoads() throws Exception { MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/stubs/**/*.json"); + .stubs("classpath:/stubs/**/*.json").build(); assertThat(this.service.go()).isEqualTo("Hello World"); server.verify(); } diff --git a/samples/wiremock-undertow/src/test/java/com/example/WiremockMockServerApplicationTests.java b/samples/wiremock-undertow/src/test/java/com/example/WiremockMockServerApplicationTests.java index fef1ace431..f53438fc5a 100644 --- a/samples/wiremock-undertow/src/test/java/com/example/WiremockMockServerApplicationTests.java +++ b/samples/wiremock-undertow/src/test/java/com/example/WiremockMockServerApplicationTests.java @@ -28,7 +28,7 @@ public class WiremockMockServerApplicationTests { public void contextLoads() throws Exception { MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/stubs"); + .stubs("classpath:/stubs").build(); assertThat(this.service.go()).isEqualTo("Hello World"); server.verify(); } diff --git a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockRestServiceServer.java b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockRestServiceServer.java index 65aa11dc37..c4ffd9bc24 100644 --- a/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockRestServiceServer.java +++ b/spring-cloud-contract-wiremock/src/main/java/org/springframework/cloud/contract/wiremock/WireMockRestServiceServer.java @@ -16,23 +16,33 @@ package org.springframework.cloud.contract.wiremock; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + import java.io.IOException; import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.client.MockRestServiceServer; +import org.springframework.test.web.client.MockRestServiceServer.MockRestServiceServerBuilder; +import org.springframework.test.web.client.ResponseActions; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import com.github.tomakehurst.wiremock.common.Json; +import com.github.tomakehurst.wiremock.http.HttpHeader; +import com.github.tomakehurst.wiremock.http.ResponseDefinition; +import com.github.tomakehurst.wiremock.matching.MultiValuePattern; +import com.github.tomakehurst.wiremock.matching.RequestPattern; import com.github.tomakehurst.wiremock.stubbing.StubMapping; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - /** * Convenience class for loading WireMock stubs into a {@link MockRestServiceServer}. In * this way using a {@link RestTemplate} can mock the responses from a server using @@ -49,10 +59,17 @@ public class WireMockRestServiceServer { private String baseUrl = ""; - private MockRestServiceServer server; + private MockRestServiceServerBuilder builder; + + private List locations = new ArrayList(); private WireMockRestServiceServer(RestTemplate restTemplate) { - this.server = MockRestServiceServer.bindTo(restTemplate).build(); + this.builder = MockRestServiceServer.bindTo(restTemplate); + } + + public WireMockRestServiceServer ignoreExpectOrder(boolean ignoreExpectOrder) { + this.builder.ignoreExpectOrder(ignoreExpectOrder); + return this; } public WireMockRestServiceServer suffix(String suffix) { @@ -65,8 +82,14 @@ public class WireMockRestServiceServer { return this; } - public MockRestServiceServer stubs(String... locations) { - for (String location : locations) { + public WireMockRestServiceServer stubs(String... locations) { + this.locations.addAll(Arrays.asList(locations)); + return this; + } + + public MockRestServiceServer build() { + MockRestServiceServer server = builder.build(); + for (String location : this.locations) { try { if (!StringUtils.getFilename(location).contains(".") && !location.contains("*")) { @@ -80,11 +103,12 @@ public class WireMockRestServiceServer { mapping = Json .read(StreamUtils.copyToString(resource.getInputStream(), Charset.defaultCharset()), StubMapping.class); - this.server - .expect(requestTo( - this.baseUrl + mapping.getRequest().getUrlPath())) - .andRespond(withSuccess(mapping.getResponse().getBody(), - MediaType.TEXT_PLAIN)); + ResponseActions expect = server.expect( + requestTo(this.baseUrl + mapping.getRequest().getUrlPath())); + requestHeaders(expect, mapping.getRequest()); + expect.andRespond(withSuccess(mapping.getResponse().getBody(), + contentType(mapping.getResponse())) + .headers(responseHeaders(mapping.getResponse()))); } } catch (IOException e) { @@ -92,7 +116,41 @@ public class WireMockRestServiceServer { e); } } - return this.server; + return server; + } + + private void requestHeaders(ResponseActions expect, RequestPattern request) { + if (request.getHeaders() != null) { + for (final String header : request.getHeaders().keySet()) { + final MultiValuePattern pattern = request.getHeaders().get(header); + // TODO: match the headers + } + } + } + + private HttpHeaders responseHeaders(ResponseDefinition response) { + HttpHeaders headers = new HttpHeaders(); + if (response.getHeaders() != null) { + for (HttpHeader header : response.getHeaders().all()) { + if (!header.keyEquals("Content-Type")) { + for (String value : header.values()) { + headers.add(header.key(), value); + } + } + } + } + return headers; + } + + private MediaType contentType(ResponseDefinition response) { + String value = null; + if (response.getHeaders() != null) { + HttpHeader header = response.getHeaders().getHeader("Content-Type"); + if (header != null) { + value = header.firstValue(); + } + } + return value == null ? MediaType.TEXT_PLAIN : MediaType.valueOf(value); } public static WireMockRestServiceServer with(RestTemplate restTemplate) { diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockHttpsPortApplicationTests.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockHttpsPortApplicationTests.java index 49ba82b61c..4d8ac28501 100644 --- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockHttpsPortApplicationTests.java +++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/AutoConfigureWireMockHttpsPortApplicationTests.java @@ -17,7 +17,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest(classes = WiremockTestsApplication.class, properties = "app.baseUrl=https://localhost:${wiremock.server.https-port}", webEnvironment = WebEnvironment.NONE) @DirtiesContext -@AutoConfigureWireMock(httpsPort = 9999) +@AutoConfigureWireMock(httpsPort = 9999, port=0) public class AutoConfigureWireMockHttpsPortApplicationTests { @Autowired diff --git a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockMockServerApplicationTests.java b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockMockServerApplicationTests.java index d1535f5f2e..f90d670fa3 100644 --- a/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockMockServerApplicationTests.java +++ b/spring-cloud-contract-wiremock/src/test/java/org/springframework/cloud/contract/wiremock/WiremockMockServerApplicationTests.java @@ -3,33 +3,51 @@ package org.springframework.cloud.contract.wiremock; import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.http.HttpMethod; +import org.springframework.http.RequestEntity; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; -@RunWith(SpringRunner.class) -@SpringBootTest(classes=WiremockTestsApplication.class, webEnvironment=WebEnvironment.NONE) -@DirtiesContext public class WiremockMockServerApplicationTests { - @Autowired - private RestTemplate restTemplate; - - @Autowired - private Service service; + private RestTemplate restTemplate = new RestTemplate(); @Test - public void contextLoads() throws Exception { + public void simpleGet() throws Exception { MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/mappings"); - assertThat(this.service.go()).isEqualTo("Hello World"); + .stubs("classpath:/mappings/resource.json").build(); + assertThat(restTemplate.getForObject("http://example.org/resource", String.class)) + .isEqualTo("Hello World"); server.verify(); } + @Test + public void simplePost() throws Exception { + MockRestServiceServer server = WireMockRestServiceServer.with(this.restTemplate) // + .baseUrl("http://example.org") // + .stubs("classpath:/mappings/poster.json").build(); + assertThat(restTemplate.postForObject("http://example.org/poster", "greeting", + String.class)).isEqualTo("Hello World"); + server.verify(); + } + + @Test + public void postWithHeader() throws Exception { + WireMockRestServiceServer.with(this.restTemplate) // + .baseUrl("http://example.org") // + .stubs("classpath:/mappings/*.json").ignoreExpectOrder(true).build(); + assertThat(restTemplate.exchange("http://example.org/poster", HttpMethod.POST, + RequestEntity.EMPTY, String.class).getBody()).isEqualTo("Accepted World"); + } + + @Test + public void simpleGetWithAllStubs() throws Exception { + WireMockRestServiceServer.with(this.restTemplate) // + .baseUrl("http://example.org") // + .stubs("classpath:/mappings").ignoreExpectOrder(true).build(); + assertThat(restTemplate.getForObject("http://example.org/resource", String.class)) + .isEqualTo("Hello World"); + } + } diff --git a/spring-cloud-contract-wiremock/src/test/resources/mappings/accept.json b/spring-cloud-contract-wiremock/src/test/resources/mappings/accept.json new file mode 100644 index 0000000000..54d3a13c51 --- /dev/null +++ b/spring-cloud-contract-wiremock/src/test/resources/mappings/accept.json @@ -0,0 +1,11 @@ +{ + "request" : { + "urlPath" : "/poster", + "method" : "POST", + "headers" : { "Accept" : { "equalTo" : "text/plain" }} + }, + "response" : { + "status" : 200, + "body" : "Accepted World" + } +} \ No newline at end of file diff --git a/spring-cloud-contract-wiremock/src/test/resources/mappings/poster.json b/spring-cloud-contract-wiremock/src/test/resources/mappings/poster.json new file mode 100644 index 0000000000..aaf337ec6f --- /dev/null +++ b/spring-cloud-contract-wiremock/src/test/resources/mappings/poster.json @@ -0,0 +1,10 @@ +{ + "request" : { + "urlPath" : "/poster", + "method" : "POST" + }, + "response" : { + "status" : 200, + "body" : "Hello World" + } +} \ No newline at end of file