Add header matchers for mock http server

Wrapping the WireMock matcher in a Hamcrest matcher, and also
using WireMock's native support for sorting mappings, so the
most specific match comes first.
This commit is contained in:
Dave Syer
2016-10-11 14:58:09 +02:00
parent 103668c669
commit 67e75fd2c6
4 changed files with 74 additions and 10 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.contract.wiremock;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.http.HttpHeaders;
@@ -37,9 +39,11 @@ import java.util.List;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.http.HttpHeader;
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;
@@ -147,14 +151,12 @@ public class WireMockRestServiceServer {
*/
public MockRestServiceServer build() {
MockRestServiceServer server = this.builder.build();
SortedConcurrentMappingSet mappings = new SortedConcurrentMappingSet();
for (String location : this.locations) {
try {
for (Resource resource : this.resolver.getResources(pattern(location))) {
StubMapping mapping = mapping(resource);
ResponseActions expect = server
.expect(requestTo(request(mapping.getRequest())));
requestHeaders(expect, mapping.getRequest());
expect.andRespond(response(mapping.getResponse()));
mappings.add(mapping);
}
}
catch (IOException e) {
@@ -162,6 +164,12 @@ public class WireMockRestServiceServer {
e);
}
}
for (StubMapping mapping : mappings) {
ResponseActions expect = server
.expect(requestTo(request(mapping.getRequest())));
requestHeaders(expect, mapping.getRequest());
expect.andRespond(response(mapping.getResponse()));
}
return server;
}
@@ -194,10 +202,22 @@ public class WireMockRestServiceServer {
if (request.getHeaders() != null) {
for (final String header : request.getHeaders().keySet()) {
final MultiValuePattern pattern = request.getHeaders().get(header);
// TODO: match the headers
if ("equalTo".equals(pattern.getName())) {
expect.andExpect(header(header, pattern.getExpected()));
}
expect.andExpect(header(header, new BaseMatcher<String>() {
@Override
public boolean matches(Object item) {
return pattern.match(
new MultiValue(header, Arrays.asList((String) item)))
.isExactMatch();
}
@Override
public void describeTo(Description description) {
description
.appendText("should match header: " + header + " with ")
.appendText(pattern.getExpected());
}
}));
}
}
}

View File

@@ -67,14 +67,36 @@ public class WiremockMockServerApplicationTests {
@Test
public void postWithHeader() throws Exception {
WireMockRestServiceServer.with(this.restTemplate) //
.baseUrl("http://example.org") //
.stubs("classpath:/mappings/*.json").ignoreExpectOrder(true).build();
.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");
}
@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");
}
@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();
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 simpleGetWithAllStubs() throws Exception {
WireMockRestServiceServer.with(this.restTemplate) //

View File

@@ -0,0 +1,11 @@
{
"request" : {
"urlPath" : "/poster",
"method" : "POST",
"headers" : { "Accept" : { "contains" : "v.foo" }}
},
"response" : {
"status" : 200,
"body" : "Foo World"
}
}

View File

@@ -0,0 +1,11 @@
{
"request" : {
"urlPath" : "/poster",
"method" : "POST",
"headers" : { "Accept" : { "matches" : ".*/v.bar" }}
},
"response" : {
"status" : 200,
"body" : "Bar World"
}
}