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
-
How to use Pact’s Java library
-
Eric Deandrea and Holly Cummins recently spoke about contract testing with Pact. Watch the replay and view the slides if you’d like to learn more about contract testing and see the Pact extensions in action.
-
The Quarkus Superheroes sample includes Pact tests