Skip to content

Using WireMock with Pact

WireMock Pact will get the requests from WireMock and create Pact JSON files on the filesystem. The Pact JSON can be published to a Pactflow broker.

WireMock Pact contains:

  • wiremock-pact-lib - A library that can transform WireMock ServeEvent:s to Pact JSON.
  • wiremock-pact-extension-junit5 - A WireMock extension, and JUnit 5, that is intended to ease usage of the library.
  • wiremock-pact-example-springboot-app - A SpringBoot application that shows how it can be used.

WireMock Pact is released to Maven Central. And available on GitHub.

The extension is both a WireMock extension and a JUnit 5 extension. When using wiremock-spring-boot it can be configured like this in a base class of your tests:

import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.maciejwalkowiak.wiremock.spring.ConfigureWireMock;
import com.maciejwalkowiak.wiremock.spring.EnableWireMock;
import com.maciejwalkowiak.wiremock.spring.WireMockConfigurationCustomizer;
import org.junit.jupiter.api.extension.RegisterExtension;
import se.bjurr.wiremockpact.wiremockpactextensionjunit5.WireMockPactExtension;
import se.bjurr.wiremockpact.wiremockpactlib.api.WireMockPactConfig;
@EnableWireMock({
@ConfigureWireMock(
name = "wiremock-service-name",
property = "wiremock.server.url",
stubLocation = "wiremock",
configurationCustomizers = {WireMockPactBaseTest.class})
})
public class WireMockPactBaseTest implements WireMockConfigurationCustomizer {
@RegisterExtension
static WireMockPactExtension WIREMOCK_PACT_EXTENSION =
new WireMockPactExtension(
WireMockPactConfig.builder() //
.setConsumerDefaultValue("WireMockPactExample") //
.setProviderDefaultValue("UnknownProvider") //
.setPactJsonFolder("src/test/resources/pact-json"));
@Override
public void customize(
final WireMockConfiguration configuration, final ConfigureWireMock options) {
configuration.extensions(WIREMOCK_PACT_EXTENSION);
}
}

It can be used as a library.

public class ExampleTest {
private static WireMockServer server;
private static WireMockPactApi wireMockPactApi;
@BeforeAll
public static void beforeEach() throws IOException {
server = new WireMockServer();
server.start();
stubFor(
post(anyUrl())
.willReturn(
ok()
.withHeader("content-type", "application/json")
.withBody("""
{"a":"b"}
"""))
.withMetadata(
new Metadata(
Map.of(
WireMockPactMetadata.METADATA_ATTR,
new WireMockPactMetadata()
.setProvider("some-specific-provider")))));
wireMockPactApi =
WireMockPactApi.create(
new WireMockPactConfig()
.setConsumerDefaultValue("my-service")
.setProviderDefaultValue("unknown-service")
.setPactJsonFolder("the/pact-json/folder"));
wireMockPactApi.clearAllSaved();
}
@Test
public void testInvoke() {
// Do stuff that invokes WireMock...
}
@AfterAll
public static void after() {
for (final ServeEvent serveEvent : server.getAllServeEvents()) {
wireMockPactApi.addServeEvent(serveEvent);
}
// Save pact-json to folder given in WireMockPactApi
wireMockPactApi.saveAll();
server.stop();
}
}

Mappings metadata - Set provider in mapping

Section titled “Mappings metadata - Set provider in mapping”

You can adjust any mappings file like this to specify the provider of a mapping in its metadata field:

{
"id" : "d68fb4e2-48ed-40d2-bc73-0a18f54f3ece",
"request" : {
"urlPattern" : "/animals/1",
"method" : "GET"
},
"response" : {
"status" : 202
},
"uuid" : "d68fb4e2-48ed-40d2-bc73-0a18f54f3ece",
"metadata": {
"wireMockPactSettings": {
"provider":"some-other-system"
}
}
}

Or programmatically:

stubFor(
post(anyUrl())
.withMetadata(
new Metadata(
Map.of(
WireMockPactMetadata.METADATA_ATTR,
new WireMockPactMetadata()
.setProvider("some-specific-provider")))));

Pact has a CLI tool that can be used for publishing the contracts. But it requires Ruby or Docker. If you don’t have that, perhaps curl is an option. There is a shell script here that can also be used via NPM.

You may want to use something like git-changelog-command-line to get the next version.

There is a test-server at https://test.pactflow.io/ that can be accessed with user dXfltyFMgNOFZAxr8io9wJ37iUpY42M and password O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1.

Terminal window
current_version=$(npx git-changelog-command-line \
--patch-version-pattern "^fix.*" \
--print-current-version)
git_hash=`git rev-parse --short HEAD`
participant_version_number="$current_version-$git_hash"
npx pactflow-publish-sh \
--username=dXfltyFMgNOFZAxr8io9wJ37iUpY42M \
--password=O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1 \
--pactflow-broker-url=https://test.pactflow.io/contracts/publish \
--build-url=http://whatever/ \
--pact-json-folder=wiremock-pact-example-springboot-app/src/test/resources/pact-json \
--participant-version-number=$participant_version_number