Introduced adding of custom WireMock extensions (#429)
without this change we set only a single extension "response-transformer" without an option to provide any other ones with this change we introduce the "spring.factories" based extension model. It's enough to provide your own implementation of `org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions` and register it in `spring.factories`. That way you can control all extensions (request / response). fixes #425
This commit is contained in:
committed by
GitHub
parent
4a46760ee2
commit
0758f4ec38
@@ -8,27 +8,28 @@ import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
|
||||
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
|
||||
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
|
||||
import com.github.tomakehurst.wiremock.extension.Extension;
|
||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.cloud.contract.stubrunner.HttpServerStub;
|
||||
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsEscapeHelper;
|
||||
import org.springframework.cloud.contract.verifier.builder.handlebars.HandlebarsJsonPathHelper;
|
||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.DefaultResponseTransformer;
|
||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions;
|
||||
import org.springframework.cloud.contract.wiremock.WireMockSpring;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import wiremock.com.github.jknack.handlebars.Helper;
|
||||
|
||||
/**
|
||||
@@ -47,18 +48,32 @@ public class WireMockHttpServerStub implements HttpServerStub {
|
||||
private WireMockConfiguration config() {
|
||||
if (ClassUtils.isPresent("org.springframework.cloud.contract.wiremock.WireMockSpring", null)) {
|
||||
return WireMockSpring.options()
|
||||
.extensions(responseTemplateTransformer());
|
||||
.extensions(responseTransformers());
|
||||
}
|
||||
return new WireMockConfiguration().extensions(responseTemplateTransformer());
|
||||
return new WireMockConfiguration().extensions(responseTransformers());
|
||||
}
|
||||
|
||||
private ResponseTemplateTransformer responseTemplateTransformer() {
|
||||
return new ResponseTemplateTransformer(false, helpers());
|
||||
private Extension[] responseTransformers() {
|
||||
List<WireMockExtensions> wireMockExtensions = SpringFactoriesLoader
|
||||
.loadFactories(WireMockExtensions.class, null);
|
||||
List<Extension> extensions = new ArrayList<>();
|
||||
if (!wireMockExtensions.isEmpty()) {
|
||||
for (WireMockExtensions wireMockExtension : wireMockExtensions) {
|
||||
extensions.addAll(wireMockExtension.extensions());
|
||||
}
|
||||
} else {
|
||||
extensions.add(new DefaultResponseTransformer(false, helpers()));
|
||||
}
|
||||
return extensions.toArray(new Extension[extensions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this if you want to register your own helpers
|
||||
*
|
||||
* @deprecated - please use the {@link WireMockExtensions} mechanism and pass
|
||||
* the helpers in your implementation
|
||||
*/
|
||||
@Deprecated
|
||||
protected Map<String, Helper> helpers() {
|
||||
Map<String, Helper> helpers = new HashMap<>();
|
||||
helpers.put(HandlebarsJsonPathHelper.NAME, new HandlebarsJsonPathHelper());
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.springframework.cloud.contract.stubrunner.provider.wiremock
|
||||
|
||||
import com.github.tomakehurst.wiremock.common.FileSource
|
||||
import com.github.tomakehurst.wiremock.extension.Extension
|
||||
import com.github.tomakehurst.wiremock.extension.Parameters
|
||||
import com.github.tomakehurst.wiremock.extension.ResponseTransformer
|
||||
import com.github.tomakehurst.wiremock.http.Request
|
||||
import com.github.tomakehurst.wiremock.http.Response
|
||||
|
||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.DefaultResponseTransformer
|
||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions
|
||||
|
||||
/**
|
||||
* Extension that registers the default response transformer and a custom one too
|
||||
*/
|
||||
class TestWireMockExtensions implements WireMockExtensions {
|
||||
@Override
|
||||
List<Extension> extensions() {
|
||||
return [
|
||||
new DefaultResponseTransformer(),
|
||||
new CustomExtension()
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class CustomExtension extends ResponseTransformer {
|
||||
|
||||
/**
|
||||
* We expect the mapping to contain "foo-transformer" in the list
|
||||
* of "response-transformers" in the stub mapping
|
||||
*/
|
||||
@Override
|
||||
String getName() {
|
||||
return "foo-transformer"
|
||||
}
|
||||
|
||||
/**
|
||||
* Transformer returns the "surprise!" body regardless of what you
|
||||
* the stub mapping returns
|
||||
*/
|
||||
@Override
|
||||
Response transform(Request request, Response response, FileSource files, Parameters parameters) {
|
||||
return new Response(response.status, response.statusMessage,
|
||||
"surprise!", response.headers, response.wasConfigured(), response.fault, response.fromProxy)
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't want this extension to be applied to every single mapping.
|
||||
* We just want this to take place when a mapping explicitly expresses that in the
|
||||
* "response-transformers" section
|
||||
*/
|
||||
@Override
|
||||
boolean applyGlobally() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -23,31 +23,35 @@ import spock.lang.Specification
|
||||
|
||||
import org.springframework.boot.test.rule.OutputCapture
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate
|
||||
import org.springframework.web.client.RestTemplate
|
||||
|
||||
class WireMockHttpServerStubSpec extends Specification {
|
||||
public static
|
||||
final File MAPPING_DESCRIPTOR = new File('src/test/resources/repository/mappings/spring/cloud/ping/ping.json')
|
||||
final File MAPPING_DESCRIPTOR = new File('src/test/resources/transformers.json')
|
||||
|
||||
@Rule OutputCapture capture = new OutputCapture()
|
||||
|
||||
def 'should describe stub mapping'() {
|
||||
given:
|
||||
WireMockHttpServerStub mappingDescriptor = new WireMockHttpServerStub().start() as WireMockHttpServerStub
|
||||
|
||||
WireMockHttpServerStub mappingDescriptor = new WireMockHttpServerStub().start() as WireMockHttpServerStub
|
||||
when:
|
||||
StubMapping mapping = mappingDescriptor.getMapping(MAPPING_DESCRIPTOR)
|
||||
|
||||
StubMapping mapping = mappingDescriptor.getMapping(MAPPING_DESCRIPTOR)
|
||||
then:
|
||||
with(mapping) {
|
||||
assert request.method == RequestMethod.GET
|
||||
assert request.url == '/ping'
|
||||
assert response.status == 200
|
||||
assert response.body == 'pong'
|
||||
assert response.headers.contentTypeHeader.mimeTypePart() == 'text/plain'
|
||||
}
|
||||
|
||||
with(mapping) {
|
||||
assert request.method == RequestMethod.GET
|
||||
assert request.url == '/ping'
|
||||
assert response.status == 200
|
||||
assert response.body == 'pong'
|
||||
assert response.headers.contentTypeHeader.mimeTypePart() == 'text/plain'
|
||||
}
|
||||
when:
|
||||
mappingDescriptor.registerMappings([MAPPING_DESCRIPTOR])
|
||||
then:
|
||||
noExceptionThrown()
|
||||
expect:
|
||||
"surprise!" == new RestTemplate().getForObject("http://localhost:" + mappingDescriptor.port() + "/ping", String.class)
|
||||
cleanup:
|
||||
mappingDescriptor.stop()
|
||||
mappingDescriptor.stop()
|
||||
}
|
||||
|
||||
def 'should make WireMock print out logs on INFO'() {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions=\
|
||||
org.springframework.cloud.contract.stubrunner.provider.wiremock.TestWireMockExtensions
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/ping"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "pong",
|
||||
"headers": {
|
||||
"Content-Type": "text/plain"
|
||||
},
|
||||
"transformers" : [ "response-template", "foo-transformer" ]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user