This project aims to create configurable WireMock Stubs (http://wiremock.org/) and JSON messages from Pacts (https://docs.pact.io/) for leaner integration testing:
- Fully support all regex based rules in Pact, i.e. allow regex based url path
- Allow for pact verified manipulation of responses/messages, i.e. to inject test data expectations
- *currently only json payloads are supported
- Allow for pact verified concrete request pattern (wiremock only), i.e. for parallel test execution, for otherwise
regex based pact rules of url path, query params and request body
- *currently only json payloads are supported
Pact2WireMock uses the WireMock Stubbing API to configure a running WireMock instance. PactStubs can load pacts from PactBroker (https://github.com/pact-foundation/pact_broker), from folder or urls.
Supported Pact-jvm versions:
pact-stubs version | pact-jvm version | Pact Spec version |
---|---|---|
3.0.1 | 4.2.21 | V3 |
3.0.0 | 4.2.20 | V3 |
2.x.x | 4.1.28 | V3 |
1.x.x | 4.0.10 | V3 |
Add to your java project as dependency (maven):
<dependency>
<groupId>de.eosts</groupId>
<artifactId>pact-stubs</artifactId>
<version>3.0.0</version>
</dependency>
PactStubs itself requires at least (and will include transitively):
com.github.tomakehurst:wiremock-jre8:2.35.1
au.com.dius:pact-jvm-provider-junit:4.2.21
au.com.dius:pact-jvm-consumer-junit:4.2.21
Pact2WireMock needs to be configured to load Pacts (PactInteractionLoader) and requires a WireMock instance.
class Example {
Pact2WireMock pact2WireMock;
public void setup() {
PactInteractionLoader pactInteractionLoader = PactInteractionLoader.folderBuilder().path(pathToPacts).build();
// PactInteractionLoader pactInteractionLoader = PactInteractionLoader.pactBrokerBuilder()
// .pactBrokerHost("pactBrokerHost")
// .pactBrokerPort("pactBrokerPort")
// .build();
// PactInteractionLoader pactInteractionLoader = PactInteractionLoader.urlsBuilder().urls(new String[]{"url"}).build();
pact2WireMock = new Pact2WireMock(pactInteractionLoader, new WireMock(mockServerHost, mockserverPort));
}
public void stubFromPact() {
// creates a stub from an interaction defined by description and (optional) provider state
pact2WireMock.stubFor(InteractionIdentifier.builder()
.consumer("consumer").provider("provider").description("description").providerState("providerState"));
// creates stub with additional response customization: sets the value 'testId' to jsonPath '$.example.id'
pact2WireMock.stubFor("consumer", "provider", "pact description", new JsonPathSetCommand("$.example.id", "testId"));
// creates stub with specific request url, i.e. where url path in pact is a regex expression (e.g. /api/resource/(.+)/property)
pact2WireMock.stubFor("consumer", "provider", "pact description", SpecificRequestSpec.builder().urlPath("/api/resource/12345/property").build());
}
}
...
Currently setting values and renaming keys via JsonPath is supported. These are wrapped by JsonPathCommands.
JsonPathCommand | Description | Comments |
---|---|---|
JsonPathSetCommand | overwrite existing property's value | (* throws com.jayway.jsonpath.PathNotFoundException if property doesn't exist) |
JsonPathPutCommand | add new property | (* this is only useful for optional fields, which are not represented in pact contracts. Usage might indicate a missing pact for the optional field or provider interface is too generic) |
JsonPathRenameKeyCommand | rename existing key | (* throws com.jayway.jsonpath.PathNotFoundException if property doesn't exist) |
JsonPathAddToArrayCommand | add object to existing array | (* throws com.jayway.jsonpath.PathNotFoundException if property doesn't exist) |
JsonPathDeleteCommand | delete key or element in array | (* throws com.jayway.jsonpath.PathNotFoundException if property doesn't exist) |
JsonPathMapCommand | set a value based on current value and given map function | (* throws com.jayway.jsonpath.PathNotFoundException if property doesn't exist) |
Since manipulation of responses/message could violate the respective pact, a ResponseComparisonResultException is thrown if the underlying pact comparison finds differences. In rare cases it might be necessary to create responses, that do not pass pact comparison (i.e. if json keys have dynamic, value-like semantics). For those cases, the thrown ResponseComparisonResultException can be caught and provides access to found diffs for further analysis.
./gradlew test
We use SemVer for versioning.