diff --git a/README.md b/README.md
index 83465b496..1f0f01d93 100644
--- a/README.md
+++ b/README.md
@@ -649,4 +649,9 @@ It covers different usages:
2. from a request scoped service
3. from a REST controller endpoint (using `@RestController)
-More information about this extension in https://quarkus.io/guides/spring-cache.
\ No newline at end of file
+More information about this extension in https://quarkus.io/guides/spring-cache.
+
+
+### `test-tooling/pact`
+
+Verifies, that quarkus works correctly with third-party tool called Pact-JVM
diff --git a/pom.xml b/pom.xml
index c71fc0fe9..083b3c3f6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -470,6 +470,18 @@
scheduling/spring
+
+ test-tooling
+
+ true
+
+ all-modules
+
+
+
+ test-tooling/pact
+
+
native
diff --git a/test-tooling/pact/pom.xml b/test-tooling/pact/pom.xml
new file mode 100644
index 000000000..44593d36a
--- /dev/null
+++ b/test-tooling/pact/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ io.quarkus.ts.qe
+ parent
+ 1.0.0-SNAPSHOT
+ ../..
+
+ pact
+ jar
+ Quarkus QE TS: Test Tooling: Pact
+
+ 4.0.10
+
+
+
+ au.com.dius
+ pact-jvm-consumer-junit5
+ ${pact.version}
+
+
+ au.com.dius
+ pact-jvm-consumer-java8
+ ${pact.version}
+
+
+ au.com.dius
+ pact-jvm-provider-junit5
+ ${pact.version}
+
+
+
+ io.quarkus
+ quarkus-resteasy-reactive
+
+
+ io.quarkus
+ quarkus-arc
+ test
+
+
+
diff --git a/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ConsumerPactTest.java b/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ConsumerPactTest.java
new file mode 100644
index 000000000..6359f7fe9
--- /dev/null
+++ b/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ConsumerPactTest.java
@@ -0,0 +1,46 @@
+package io.quarkus.ts.http.pact;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import io.pactfoundation.consumer.dsl.LambdaDsl;
+import io.quarkus.test.junit.QuarkusTest;
+
+import au.com.dius.pact.consumer.MessagePactBuilder;
+import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
+import au.com.dius.pact.consumer.junit5.PactTestFor;
+import au.com.dius.pact.consumer.junit5.ProviderType;
+import au.com.dius.pact.core.model.annotations.Pact;
+import au.com.dius.pact.core.model.messaging.Message;
+import au.com.dius.pact.core.model.messaging.MessagePact;
+
+@QuarkusTest
+@Tag("QUARKUS-1024")
+@ExtendWith(PactConsumerTestExt.class)
+@PactTestFor(providerName = "TheProvider", providerType = ProviderType.ASYNCH)
+public class ConsumerPactTest {
+
+ @Pact(consumer = "TheConsumer")
+ public MessagePact createPact(MessagePactBuilder builder) {
+ var body = LambdaDsl.newJsonBody((it) -> {
+ it.stringType("payload", "Hello there");
+ }).build();
+
+ return builder
+ .expectsToReceive("a message with a payload")
+ .withMetadata(new HashMap<>())
+ .withContent(body)
+ .toPact();
+ }
+
+ @Test
+ void test(List messages) {
+ Assertions.assertEquals(1, messages.size());
+ Assertions.assertEquals("{\"payload\":\"Hello there\"}", messages.get(0).contentsAsString());
+ }
+}
diff --git a/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ProviderPactTest.java b/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ProviderPactTest.java
new file mode 100644
index 000000000..47a1bfd6a
--- /dev/null
+++ b/test-tooling/pact/src/test/java/io/quarkus/ts/http/pact/ProviderPactTest.java
@@ -0,0 +1,38 @@
+package io.quarkus.ts.http.pact;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+import au.com.dius.pact.provider.PactVerifyProvider;
+import au.com.dius.pact.provider.junit.Provider;
+import au.com.dius.pact.provider.junit.loader.PactFolder;
+import au.com.dius.pact.provider.junit5.AmpqTestTarget;
+import au.com.dius.pact.provider.junit5.PactVerificationContext;
+import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;
+
+@QuarkusTest
+@Tag("QUARKUS-1024")
+@Provider("TheProvider")
+@PactFolder("src/test/resources/pacts")
+public class ProviderPactTest {
+
+ @BeforeEach
+ void before(PactVerificationContext context) {
+ context.setTarget(new AmpqTestTarget());
+ }
+
+ @TestTemplate
+ @ExtendWith(PactVerificationInvocationContextProvider.class)
+ void testTemplate(PactVerificationContext context) {
+ context.verifyInteraction();
+ }
+
+ @PactVerifyProvider("a message with a payload")
+ public String verifyMessageForOrder() {
+ return "{\"payload\": \"somepayload\"}";
+ }
+}
diff --git a/test-tooling/pact/src/test/resources/pacts/TheConsumer-TheProvider.json b/test-tooling/pact/src/test/resources/pacts/TheConsumer-TheProvider.json
new file mode 100644
index 000000000..22f319387
--- /dev/null
+++ b/test-tooling/pact/src/test/resources/pacts/TheConsumer-TheProvider.json
@@ -0,0 +1,39 @@
+{
+ "consumer": {
+ "name": "TheConsumer"
+ },
+ "provider": {
+ "name": "TheProvider"
+ },
+ "messages": [
+ {
+ "description": "a message with a payload",
+ "metaData": {
+ "contentType": "application/json"
+ },
+ "contents": {
+ "payload": "thePayload"
+ },
+ "matchingRules": {
+ "body": {
+ "$.payload": {
+ "matchers": [
+ {
+ "match": "type"
+ }
+ ],
+ "combine": "AND"
+ }
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "pactSpecification": {
+ "version": "3.0.0"
+ },
+ "pact-jvm": {
+ "version": "4.0.6"
+ }
+ }
+}