Pact Consumer
This extension ensures Pact consumer libraries works well with Quarkus applications, including with continuous testing. It is based on version 4.3.17 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>0.2.1</version>
<scope>provided</scope>
</dependency>
Note the provided
scope, rather than test
or default. This is needed for the tests to pass in continuous testing mode.
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 (2)
public class ConsumerTest {
(3)
@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");
return builder.given("test GET") (4)
.uponReceiving("GET REQUEST")
.path("/alpaca")
.method("GET")
.willRespondWith()
.status(200)
.headers(headers)
.body(" {\n" + (5)
" \"colour\": \"black\",\n" +
" \"name\": \"floppy\"\n" +
" }")
.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 | Needed to enable dependency injection of the rest client. |
3 | The consumer under test. |
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
-
If continuous testing is being used, the dependency scope cannot be
test
. Theprovided
scope is a good alternative. -
@TestProfile
does not work in dev mode (GitHub issue) -
A harmless
java.lang.NoClassDefFoundError: org/apache/hc/client5/http/fluent/Request
message will be produced if Pact tracking is enabled (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