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 d3e93e3814..48d43e11b5 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 @@ -71,6 +71,8 @@ public class WireMockRestServiceServer { private List locations = new ArrayList(); + private boolean ignoreExpectOrder = true; + private WireMockRestServiceServer(RestTemplate restTemplate) { this.builder = MockRestServiceServer.bindTo(restTemplate); } @@ -87,12 +89,14 @@ public class WireMockRestServiceServer { /** * Flag to tell the MockRestServiceServer to ignore the order of calls when matching - * requests. + * requests. The default is true because there is an impleid ordering in the stubs + * (by url path and with more specific request matchers first). * - * @param ignoreExpectOrder flag value + * @param ignoreExpectOrder flag value (default true) * @return this */ public WireMockRestServiceServer ignoreExpectOrder(boolean ignoreExpectOrder) { + this.ignoreExpectOrder = ignoreExpectOrder; this.builder.ignoreExpectOrder(ignoreExpectOrder); return this; } @@ -151,6 +155,9 @@ public class WireMockRestServiceServer { * @return a MockRestServiceServer */ public MockRestServiceServer build() { + if (this.ignoreExpectOrder) { + builder.ignoreExpectOrder(true); // default is false + } MockRestServiceServer server = this.builder.build(); List mappings = new ArrayList<>(); for (String location : this.locations) { @@ -165,7 +172,9 @@ public class WireMockRestServiceServer { e); } } - Collections.sort(mappings, new StubMappingComparator()); + if (this.ignoreExpectOrder) { + Collections.sort(mappings, new StubMappingComparator()); + } for (StubMapping mapping : mappings) { ResponseActions expect = server .expect(requestTo(request(mapping.getRequest()))); @@ -176,7 +185,9 @@ public class WireMockRestServiceServer { } private String request(RequestPattern request) { - return this.baseUrl + (request.getUrlPath() == null ? "/" : request.getUrlPath()); + return this.baseUrl + (request.getUrlPath() == null + ? (request.getUrl() == null ? "/" : request.getUrl()) + : request.getUrlPath()); } private String pattern(String location) { @@ -253,7 +264,7 @@ public class WireMockRestServiceServer { @Override public int compare(StubMapping one, StubMapping two) { - if (one==two) { + if (one == two) { return 0; } int value = request(one.getRequest()).compareTo(request(two.getRequest())); @@ -282,7 +293,9 @@ public class WireMockRestServiceServer { } private String request(RequestPattern request) { - return (request.getUrlPath() == null ? (request.getUrl() == null ? "/" : request.getUrl()) : request.getUrlPath()); + return (request.getUrlPath() == null + ? (request.getUrl() == null ? "/" : request.getUrl()) + : request.getUrlPath()); } } 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 070badb92a..8d0be00b9d 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 @@ -67,10 +67,10 @@ public class WiremockMockServerApplicationTests { @Test public void postWithHeader() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // - .baseUrl("http://example.org") // order matters... + .baseUrl("http://example.org") // order determined by content... .stubs("classpath:/mappings/poster.json", "classpath:/mappings/accept.json") - .ignoreExpectOrder(true).build(); + .build(); assertThat( this.restTemplate .exchange( @@ -83,10 +83,10 @@ public class WiremockMockServerApplicationTests { @Test public void postWithHeaderContains() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // - .baseUrl("http://example.org") // order matters... + .baseUrl("http://example.org") // order determined by content... .stubs("classpath:/mappings/poster.json", "classpath:/mappings/header-contains.json") - .ignoreExpectOrder(true).build(); + .build(); assertThat(this.restTemplate.exchange( RequestEntity.post(new URI("http://example.org/poster")) .accept(MediaType.valueOf("application/v.foo")).build(), @@ -96,10 +96,10 @@ public class WiremockMockServerApplicationTests { @Test public void postWithHeaderMatches() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // - .baseUrl("http://example.org") // order matters... + .baseUrl("http://example.org") // order determined by content... .stubs("classpath:/mappings/poster.json", "classpath:/mappings/header-matches.json") - .ignoreExpectOrder(true).build(); + .build(); assertThat(this.restTemplate.exchange( RequestEntity.post(new URI("http://example.org/poster")) .accept(MediaType.valueOf("application/v.bar")).build(), @@ -109,10 +109,10 @@ public class WiremockMockServerApplicationTests { @Test public void postWithMoreExactHeaderMatch() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // - .baseUrl("http://example.org") // order matters... + .baseUrl("http://example.org") // order determined by content... .stubs("classpath:/mappings/header-matches.json", "classpath:/mappings/header-matches-precise.json") - .ignoreExpectOrder(true).build(); + .build(); assertThat(this.restTemplate .exchange(RequestEntity.post(new URI("http://example.org/poster")) .accept(MediaType.valueOf("application/v.bar")) @@ -120,11 +120,26 @@ public class WiremockMockServerApplicationTests { .getBody()).isEqualTo("Precise World"); } + @Test + public void postWithMoreExactHeaderMatchButOrdered() throws Exception { + WireMockRestServiceServer.with(this.restTemplate) // + .baseUrl("http://example.org") // order matters... + .stubs("classpath:/mappings/header-matches.json", + "classpath:/mappings/header-matches-precise.json") + .ignoreExpectOrder(false).build(); + assertThat(this.restTemplate + .exchange(RequestEntity.post(new URI("http://example.org/poster")) + .accept(MediaType.valueOf("application/v.bar")) + .header("X-Precise", "true").build(), String.class) + .getBody()).isEqualTo("Bar World"); + // The first one matches, not the most precise! + } + @Test public void simpleGetWithAllStubs() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/mappings").ignoreExpectOrder(true).build(); + .stubs("classpath:/mappings").build(); assertThat(this.restTemplate.getForObject("http://example.org/resource", String.class)).isEqualTo("Hello World"); } @@ -133,7 +148,7 @@ public class WiremockMockServerApplicationTests { public void simpleGetWithAllStubsInDirectoryWithPeriod() throws Exception { WireMockRestServiceServer.with(this.restTemplate) // .baseUrl("http://example.org") // - .stubs("classpath:/io.stubs/mappings").ignoreExpectOrder(true).build(); + .stubs("classpath:/io.stubs/mappings").build(); assertThat(this.restTemplate.getForObject("http://example.org/resource", String.class)).isEqualTo("Hello World"); }