Pact Consumer

This extension ensures Pact consumer libraries works well with Quarkus applications, including with continuous testing. It is based on version 4.6.14 of the Pact JVM JUnit 5 library.

Installation

To use this extension, add the io.quarkiverse:quarkus-pact-consumer extension first to your build file. Choose a 1.x version for Quarkus 3, and a 0.x version for Quarkus 2.

For instance, with Maven, add the following dependency to your POM file:

<dependency>
    <groupId>io.quarkiverse</groupId>
    <artifactId>quarkus-pact-consumer</artifactId>
    <version>1.4.2</version>
    <scope>test</scope>
</dependency>

Example usage

Use Pact as you normally would. Remember that your consumer tests should be testing your application’s code, not the behaviour of the Pact-provided mock.

For example, a simple consumer test for REST endpoints would look like this:

(1)
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "farm", port = "8085")
@PactDirectory("target/pacts")
@QuarkusTest // Needed to enable dependency injection of the rest client
public class ConsumerTest {

    (2)
    @Inject
    Knitter knitter;

    @Pact(provider = "farm", consumer = "knitter")
    public V4Pact createPact(PactDslWithProvider builder) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");

        var requestBody = newJsonBody(body -> body.stringType("colour").numberType("orderNumber")).build(); (3)

        var woolResponseBody = newJsonBody(body -> body.stringValue("colour", "white")).build(); (4)

        (5)
        return builder.uponReceiving("post request").path("/wool/order").headers(headers).method(HttpMethod.POST)
                .body(requestBody).willRespondWith().status(Status.OK.getStatusCode()).headers(headers).body(woolResponseBody)
                .toPact(V4Pact.class);

    }

    @Test
    public void testConsumption() { (6)
        String knitted = knitter.knit("irrelevant"); (7)
        assertEquals("a nice striped sweater", knitted);
    }
}
1 Add @Consumer annotations to the class, along with metadata about who the consumer is, and what provider is being used.
2 The consumer under test.
3 This defines what the body of the request could look like; we are generic and say it can be anything that meets the schema. We could be stricter and put more expectations on what the consumer sends.
4 We use the Pact DSL to define what the provider should return, given the request.
5 Here we define our mock, which is also our expectations for the provider. There is no need to verify these in this test; instead, the provider test will verify them.
6 This test is realistic (in a simplified way) of how a consumer test might look.
7 We have hardcoded the mock response, so the colour parameter we pass in is irrelevant (for this particular test) It tests how the consumer under test uses what the mock passes back, not the mock itself.

Extension Configuration Reference

For the moment, Pact needs to be configured by the normal Pact system properties.

Known limitations

  • Consumer tests cannot directly access the Pact MockServer when continuous testing is being used (GitHub issue)

  • @TestProfile does not work in dev mode (GitHub issue)

Samples and resources