Upgrading WireMock to 2.5.1

fixes #202
This commit is contained in:
Marcin Grzejszczak
2017-02-02 17:15:04 +01:00
parent caf0452c4b
commit eaea0a6d21
22 changed files with 323 additions and 101 deletions

View File

@@ -20,7 +20,6 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
@@ -39,7 +38,6 @@ import org.springframework.util.StringUtils;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
/**
* Configuration and lifecycle for a Spring Application context that wants to run a
@@ -105,7 +103,7 @@ public class WireMockConfiguration implements SmartLifecycle {
pattern = pattern + "**/*.json";
}
for (Resource resource : resolver.getResources(pattern)) {
this.server.addStubMapping(StubMapping
this.server.addStubMapping(WireMockStubMapping
.buildFrom(StreamUtils.copyToString(resource.getInputStream(), Charset.forName("UTF-8"))));
}
}

View File

@@ -0,0 +1,12 @@
package org.springframework.cloud.contract.wiremock;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
/**
* @author Marcin Grzejszczak
*/
public class WireMockStubMapping {
public static StubMapping buildFrom(String mappingDefinition) {
return StubMapping.buildFrom(mappingDefinition);
}
}

View File

@@ -74,6 +74,19 @@ public class ResourcesFileSource implements FileSource {
throw new IllegalStateException("Cannot create file for " + name);
}
@Override public TextFile getTextFileNamed(String name) {
for (FileSource resource : this.sources) {
TextFile file = resource.getTextFileNamed(name);
try {
file.readContentsAsString();
return file;
} catch (RuntimeException e) {
// Ignore
}
}
return null;
}
@Override
public void createIfNecessary() {
throw new UnsupportedOperationException("Resource file sources are read-only");
@@ -156,4 +169,8 @@ public class ResourcesFileSource implements FileSource {
return false;
}
@Override public void deleteFile(String name) {
}
}

View File

@@ -0,0 +1,151 @@
package org.springframework.cloud.contract.wiremock.restdocs;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import com.github.tomakehurst.wiremock.client.BasicCredentials;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.client.ScenarioMappingBuilder;
import com.github.tomakehurst.wiremock.extension.Parameters;
import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.RequestMethod;
import com.github.tomakehurst.wiremock.http.ResponseDefinition;
import com.github.tomakehurst.wiremock.matching.RequestPattern;
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
import com.github.tomakehurst.wiremock.matching.StringValuePattern;
import com.github.tomakehurst.wiremock.matching.UrlPattern;
import com.github.tomakehurst.wiremock.matching.ValueMatcher;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
class BasicMappingBuilder implements ScenarioMappingBuilder {
private RequestPatternBuilder requestPatternBuilder;
private ResponseDefinitionBuilder responseDefBuilder;
private Integer priority;
private String scenarioName;
private String requiredScenarioState;
private String newScenarioState;
private UUID id = UUID.randomUUID();
private String name;
private boolean isPersistent = false;
private Map<String, Parameters> postServeActions = new LinkedHashMap<>();
BasicMappingBuilder(RequestMethod method, UrlPattern urlPattern) {
this.requestPatternBuilder = new RequestPatternBuilder(method, urlPattern);
}
BasicMappingBuilder(ValueMatcher<Request> requestMatcher) {
this.requestPatternBuilder = new RequestPatternBuilder(requestMatcher);
}
BasicMappingBuilder(String customRequestMatcherName, Parameters parameters) {
this.requestPatternBuilder = new RequestPatternBuilder(customRequestMatcherName,
parameters);
}
@Override
public BasicMappingBuilder willReturn(ResponseDefinitionBuilder responseDefBuilder) {
this.responseDefBuilder = responseDefBuilder;
return this;
}
@Override public BasicMappingBuilder atPriority(Integer priority) {
this.priority = priority;
return this;
}
@Override
public BasicMappingBuilder withHeader(String key, StringValuePattern headerPattern) {
this.requestPatternBuilder.withHeader(key, headerPattern);
return this;
}
@Override public BasicMappingBuilder withCookie(String name,
StringValuePattern cookieValuePattern) {
this.requestPatternBuilder.withCookie(name, cookieValuePattern);
return this;
}
@Override public BasicMappingBuilder withQueryParam(String key,
StringValuePattern queryParamPattern) {
this.requestPatternBuilder.withQueryParam(key, queryParamPattern);
return this;
}
@Override public BasicMappingBuilder withRequestBody(StringValuePattern bodyPattern) {
this.requestPatternBuilder.withRequestBody(bodyPattern);
return this;
}
@Override public BasicMappingBuilder inScenario(String scenarioName) {
this.scenarioName = scenarioName;
return this;
}
@Override public BasicMappingBuilder whenScenarioStateIs(String stateName) {
this.requiredScenarioState = stateName;
return this;
}
@Override public BasicMappingBuilder willSetStateTo(String stateName) {
this.newScenarioState = stateName;
return this;
}
@Override public BasicMappingBuilder withId(UUID id) {
this.id = id;
return this;
}
@Override public BasicMappingBuilder withName(String name) {
this.name = name;
return this;
}
@Override public ScenarioMappingBuilder persistent() {
this.isPersistent = true;
return this;
}
@Override public BasicMappingBuilder withBasicAuth(String username, String password) {
this.requestPatternBuilder
.withBasicAuth(new BasicCredentials(username, password));
return this;
}
@Override public <P> BasicMappingBuilder withPostServeAction(String extensionName,
P parameters) {
Parameters params = parameters instanceof Parameters ?
(Parameters) parameters :
Parameters.of(parameters);
this.postServeActions.put(extensionName, params);
return this;
}
@Override public StubMapping build() {
if (this.scenarioName == null && (this.requiredScenarioState != null
|| this.newScenarioState != null)) {
throw new IllegalStateException(
"Scenario name must be specified to require or set a new scenario state");
}
RequestPattern requestPattern = this.requestPatternBuilder.build();
ResponseDefinition response = (this.responseDefBuilder != null ?
this.responseDefBuilder :
aResponse()).build();
StubMapping mapping = new StubMapping(requestPattern, response);
mapping.setPriority(this.priority);
mapping.setScenarioName(this.scenarioName);
mapping.setRequiredScenarioState(this.requiredScenarioState);
mapping.setNewScenarioState(this.newScenarioState);
mapping.setUuid(this.id);
mapping.setName(this.name);
mapping.setPersistent(this.isPersistent);
mapping.setPostServeActions(
this.postServeActions.isEmpty() ? null : this.postServeActions);
return mapping;
}
}

View File

@@ -32,7 +32,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import com.github.tomakehurst.wiremock.client.RemoteMappingBuilder;
import com.github.tomakehurst.wiremock.client.MappingBuilder;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.matching.MatchResult;
import com.github.tomakehurst.wiremock.servlet.WireMockHttpServletRequestAdapter;
@@ -49,7 +49,7 @@ public class ContractRequestHandler implements ResultHandler {
private MediaType contentType;
private String name;
private RemoteMappingBuilder<?, ?> builder;
private MappingBuilder builder;
public ContractRequestHandler() {
}
@@ -117,7 +117,7 @@ public class ContractRequestHandler implements ResultHandler {
return map;
}
public ContractRequestHandler wiremock(RemoteMappingBuilder<?, ?> builder) {
public ContractRequestHandler wiremock(MappingBuilder builder) {
this.builder = builder;
return this;
}

View File

@@ -32,7 +32,7 @@ import org.springframework.restdocs.RestDocumentationContext;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.snippet.Snippet;
import com.github.tomakehurst.wiremock.client.RemoteMappingBuilder;
import com.github.tomakehurst.wiremock.client.MappingBuilder;
import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.http.HttpHeader;
@@ -112,11 +112,11 @@ public class WireMockSnippet implements Snippet {
.withStatus(operation.getResponse().getStatus().value());
}
private RemoteMappingBuilder<?, ?> request(Operation operation) {
private MappingBuilder request(Operation operation) {
return requestHeaders(requestBuilder(operation), operation);
}
private RemoteMappingBuilder<?, ?> requestHeaders(RemoteMappingBuilder<?, ?> request,
private MappingBuilder requestHeaders(MappingBuilder request,
Operation operation) {
org.springframework.http.HttpHeaders headers = operation.getRequest()
.getHeaders();
@@ -136,7 +136,7 @@ public class WireMockSnippet implements Snippet {
return request;
}
private RemoteMappingBuilder<?, ?> requestBuilder(Operation operation) {
private MappingBuilder requestBuilder(Operation operation) {
switch (operation.getRequest().getMethod()) {
case DELETE:
return delete(requestPattern(operation));
@@ -151,7 +151,7 @@ public class WireMockSnippet implements Snippet {
}
}
private RemoteMappingBuilder<?, ?> bodyPattern(RemoteMappingBuilder<?, ?> builder,
private MappingBuilder bodyPattern(MappingBuilder builder,
String content) {
if (this.jsonPaths != null) {
for (String jsonPath : this.jsonPaths) {

View File

@@ -0,0 +1,24 @@
package org.springframework.cloud.contract.wiremock;
import org.json.JSONException;
import org.junit.Test;
/**
* @author Marcin Grzejszczak
*/
public class WireMockStubMappingTest {
private static final String stub_2_1_7 = "{\"request\" : { \"method\" : \"GET\" }, \"response\" : { \"status\" : 200 }}";
private static final String stub_2_5_1 = "{\"id\" : \"77514bd4-a102-4478-a3c0-0fda8b905591\", \"request\" : { \"method\" : \"GET\" }, \"response\" : { \"status\" : 200 }, \"uuid\" : \"77514bd4-a102-4478-a3c0-0fda8b905591\"}";
@Test
public void should_successfully_parse_a_WireMock_2_1_7_stub() throws JSONException {
// when:
WireMockStubMapping.buildFrom(stub_2_1_7);
}
@Test
public void should_successfully_parse_a_WireMock_2_5_1_stub() throws JSONException {
// when:
WireMockStubMapping.buildFrom(stub_2_5_1);
}
}

View File

@@ -15,6 +15,7 @@ import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.cloud.contract.wiremock.WireMockStubMapping;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@@ -48,12 +49,6 @@ public class WireMockSnippetTests {
@Before
public void setup() throws IOException {
this.outputFolder = this.tmp.newFolder();
}
@Test
public void should_maintain_the_response_status_when_generating_stub()
throws Exception {
WireMockSnippet snippet = new WireMockSnippet();
RestDocumentationContext context = new RestDocumentationContext(this.getClass(),
"method", this.outputFolder);
given(this.operation.getName()).willReturn("foo");
@@ -62,12 +57,18 @@ public class WireMockSnippetTests {
.get(RestDocumentationContext.class.getName())).willReturn(context);
given(this.operation.getRequest()).willReturn(request());
given(this.operation.getResponse()).willReturn(response());
}
@Test
public void should_maintain_the_response_status_when_generating_stub()
throws Exception {
WireMockSnippet snippet = new WireMockSnippet();
snippet.document(this.operation);
File stub = new File(this.outputFolder, "stubs/foo.json");
assertThat(stub).exists();
StubMapping stubMapping = StubMapping
StubMapping stubMapping = WireMockStubMapping
.buildFrom(new String(Files.readAllBytes(stub.toPath())));
assertThat(stubMapping.getResponse().getStatus())
.isEqualTo(HttpStatus.ACCEPTED.value());
@@ -77,20 +78,13 @@ public class WireMockSnippetTests {
public void should_use_equal_to_json_pattern_for_body_when_request_content_type_is_json_when_generating_stub()
throws Exception {
WireMockSnippet snippet = new WireMockSnippet();
RestDocumentationContext context = new RestDocumentationContext(this.getClass(),
"method", this.outputFolder);
given(this.operation.getName()).willReturn("foo");
given(this.operation.getAttributes().get(anyString())).willReturn(null);
given(this.operation.getAttributes()
.get(RestDocumentationContext.class.getName())).willReturn(context);
given(this.operation.getRequest()).willReturn(requestPostWithJsonContentType());
given(this.operation.getResponse()).willReturn(response());
snippet.document(this.operation);
File stub = new File(this.outputFolder, "stubs/foo.json");
assertThat(stub).exists();
StubMapping stubMapping = StubMapping
StubMapping stubMapping = WireMockStubMapping
.buildFrom(new String(Files.readAllBytes(stub.toPath())));
assertThat(stubMapping.getRequest().getBodyPatterns().get(0))
.isInstanceOf(EqualToJsonPattern.class);