Fix order of matchers in mock server
It turns out the WireMock does not (I think) contain a comparator that helps. We have made a custom comparator that helps a bit (it orders requests with the same URL in reverse order of the number of headers matched).
This commit is contained in:
@@ -35,6 +35,8 @@ import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.github.tomakehurst.wiremock.common.Json;
|
||||
@@ -43,7 +45,6 @@ import com.github.tomakehurst.wiremock.http.MultiValue;
|
||||
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.SortedConcurrentMappingSet;
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
|
||||
@@ -151,7 +152,7 @@ public class WireMockRestServiceServer {
|
||||
*/
|
||||
public MockRestServiceServer build() {
|
||||
MockRestServiceServer server = this.builder.build();
|
||||
SortedConcurrentMappingSet mappings = new SortedConcurrentMappingSet();
|
||||
List<StubMapping> mappings = new ArrayList<>();
|
||||
for (String location : this.locations) {
|
||||
try {
|
||||
for (Resource resource : this.resolver.getResources(pattern(location))) {
|
||||
@@ -164,6 +165,7 @@ public class WireMockRestServiceServer {
|
||||
e);
|
||||
}
|
||||
}
|
||||
Collections.sort(mappings, new StubMappingComparator());
|
||||
for (StubMapping mapping : mappings) {
|
||||
ResponseActions expect = server
|
||||
.expect(requestTo(request(mapping.getRequest())));
|
||||
@@ -247,4 +249,42 @@ public class WireMockRestServiceServer {
|
||||
return value == null ? MediaType.TEXT_PLAIN : MediaType.valueOf(value);
|
||||
}
|
||||
|
||||
private static class StubMappingComparator implements Comparator<StubMapping> {
|
||||
|
||||
@Override
|
||||
public int compare(StubMapping one, StubMapping two) {
|
||||
if (one==two) {
|
||||
return 0;
|
||||
}
|
||||
int value = request(one.getRequest()).compareTo(request(two.getRequest()));
|
||||
if (value == 0) {
|
||||
|
||||
// Every mapping has a url pattern, and zero or more header patterns
|
||||
int twos = 0;
|
||||
if (two.getRequest().getHeaders() != null) {
|
||||
twos = two.getRequest().getHeaders().size();
|
||||
}
|
||||
int ones = 0;
|
||||
if (one.getRequest().getHeaders() != null) {
|
||||
ones = one.getRequest().getHeaders().size();
|
||||
}
|
||||
value = twos - ones;
|
||||
if (value == 0) {
|
||||
// Same number of header matchers
|
||||
if (two.getPriority() != null) {
|
||||
return one.getPriority() != null
|
||||
? one.getPriority() - two.getPriority() : 1;
|
||||
}
|
||||
value = (int) (one.getInsertionIndex() - two.getInsertionIndex());
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private String request(RequestPattern request) {
|
||||
return (request.getUrlPath() == null ? (request.getUrl() == null ? "/" : request.getUrl()) : request.getUrlPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,33 +68,56 @@ public class WiremockMockServerApplicationTests {
|
||||
public void postWithHeader() throws Exception {
|
||||
WireMockRestServiceServer.with(this.restTemplate) //
|
||||
.baseUrl("http://example.org") // order matters...
|
||||
.stubs("classpath:/mappings/poster.json", "classpath:/mappings/accept.json").ignoreExpectOrder(true).build();
|
||||
assertThat(this.restTemplate
|
||||
.exchange(RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.TEXT_PLAIN).build(), String.class)
|
||||
.getBody()).isEqualTo("Accepted World");
|
||||
.stubs("classpath:/mappings/poster.json",
|
||||
"classpath:/mappings/accept.json")
|
||||
.ignoreExpectOrder(true).build();
|
||||
assertThat(
|
||||
this.restTemplate
|
||||
.exchange(
|
||||
RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.TEXT_PLAIN).build(),
|
||||
String.class)
|
||||
.getBody()).isEqualTo("Accepted World");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postWithHeaderContains() throws Exception {
|
||||
WireMockRestServiceServer.with(this.restTemplate) //
|
||||
.baseUrl("http://example.org") // order matters...
|
||||
.stubs("classpath:/mappings/poster.json", "classpath:/mappings/header-contains.json").ignoreExpectOrder(true).build();
|
||||
assertThat(this.restTemplate
|
||||
.exchange(RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.valueOf("application/v.foo")).build(), String.class)
|
||||
.getBody()).isEqualTo("Foo World");
|
||||
.stubs("classpath:/mappings/poster.json",
|
||||
"classpath:/mappings/header-contains.json")
|
||||
.ignoreExpectOrder(true).build();
|
||||
assertThat(this.restTemplate.exchange(
|
||||
RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.valueOf("application/v.foo")).build(),
|
||||
String.class).getBody()).isEqualTo("Foo World");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postWithHeaderMatches() throws Exception {
|
||||
WireMockRestServiceServer.with(this.restTemplate) //
|
||||
.baseUrl("http://example.org") // order matters...
|
||||
.stubs("classpath:/mappings/poster.json", "classpath:/mappings/header-matches.json").ignoreExpectOrder(true).build();
|
||||
.stubs("classpath:/mappings/poster.json",
|
||||
"classpath:/mappings/header-matches.json")
|
||||
.ignoreExpectOrder(true).build();
|
||||
assertThat(this.restTemplate.exchange(
|
||||
RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.valueOf("application/v.bar")).build(),
|
||||
String.class).getBody()).isEqualTo("Bar World");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postWithMoreExactHeaderMatch() 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(true).build();
|
||||
assertThat(this.restTemplate
|
||||
.exchange(RequestEntity.post(new URI("http://example.org/poster"))
|
||||
.accept(MediaType.valueOf("application/v.bar")).build(), String.class)
|
||||
.getBody()).isEqualTo("Bar World");
|
||||
.accept(MediaType.valueOf("application/v.bar"))
|
||||
.header("X-Precise", "true").build(), String.class)
|
||||
.getBody()).isEqualTo("Precise World");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"request" : {
|
||||
"urlPath" : "/poster",
|
||||
"method" : "POST",
|
||||
"headers" : { "Accept" : { "matches" : ".*/v.bar" }, "X-Precise" : { "equalTo" : "true" }}
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "Precise World"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user