pact-jvm
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
Top Related Projects
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Java DSL for easy testing of REST services
Test Automation Made Simple
A tool for mocking HTTP services
OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
Quick Overview
Pact JVM is a consumer-driven contract testing tool for JVM languages. It allows you to define interactions between service consumers and providers, ensuring that they can communicate effectively. This project is part of the broader Pact ecosystem, providing support for Java, Kotlin, Scala, and other JVM languages.
Pros
- Supports multiple JVM languages, making it versatile for different tech stacks
- Integrates well with popular testing frameworks like JUnit and TestNG
- Provides a clear way to define and verify service interactions
- Helps catch integration issues early in the development process
Cons
- Learning curve can be steep for teams new to contract testing
- Setup and configuration can be complex for larger projects
- May require significant changes to existing test suites
- Performance overhead when running contract tests
Code Examples
- Defining a Pact interaction in a consumer test:
@Pact(provider = "UserService", consumer = "OrderService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("a user with ID 1 exists")
.uponReceiving("a request for user 1")
.path("/users/1")
.method("GET")
.willRespondWith()
.status(200)
.body(new PactDslJsonBody()
.integerType("id", 1)
.stringType("name", "John Doe"))
.toPact();
}
- Verifying a Pact in a provider test:
@Provider("UserService")
@PactFolder("pacts")
public class UserServiceProviderTest {
@TestTarget
public final Target target = new HttpTarget(8080);
@State("a user with ID 1 exists")
public void createUser() {
// Set up the user in the database
}
}
- Using Pact in a Spring Boot application:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Provider("UserService")
@PactBroker(host = "localhost", port = "8000")
public class UserServiceProviderTest {
@LocalServerPort
private int port;
@TestTarget
public final Target target = new HttpTarget(port);
@State("a user with ID 1 exists")
public void createUser() {
// Set up the user in the database
}
}
Getting Started
To start using Pact JVM in your project:
- Add the Pact JVM dependency to your build file (e.g., Maven):
<dependency>
<groupId>au.com.dius.pact.consumer</groupId>
<artifactId>junit5</artifactId>
<version>4.3.13</version>
<scope>test</scope>
</dependency>
- Write consumer tests defining the expected interactions.
- Generate Pact files from consumer tests.
- Implement provider tests to verify the Pact contracts.
- Run provider tests against the generated Pact files.
For more detailed instructions, refer to the official Pact JVM documentation.
Competitor Comparisons
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
Pros of pact-jvm
- More comprehensive documentation and examples
- Better integration with JVM-based testing frameworks
- Larger community and more frequent updates
Cons of pact-jvm
- Steeper learning curve for beginners
- Heavier dependency footprint
- Potentially slower test execution due to more features
Code Comparison
pact-jvm:
@Pact(consumer = "ConsumerService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("test state")
.uponReceiving("ExampleJavaConsumerPactTest test interaction")
.path("/")
.method("GET")
.willRespondWith()
.status(200)
.body("{\"condition\": true, \"name\": \"tom\"}")
.toPact();
}
pact-jvm:
@Pact(consumer = "ConsumerService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("test state")
.uponReceiving("ExampleJavaConsumerPactTest test interaction")
.path("/")
.method("GET")
.willRespondWith()
.status(200)
.body("{\"condition\": true, \"name\": \"tom\"}")
.toPact();
}
Both repositories use the same codebase, as they are the same project. The code structure and syntax are identical, focusing on creating consumer-driven contract tests for JVM-based applications.
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Pros of Testcontainers
- Provides real, lightweight, and disposable instances of databases, message brokers, and other services for integration testing
- Supports a wide range of technologies and databases out of the box
- Integrates seamlessly with popular testing frameworks like JUnit and TestNG
Cons of Testcontainers
- Requires Docker to be installed and running on the test machine
- Can be slower to start up compared to mocking or stubbing approaches
- May consume more system resources, especially when running multiple containers
Code Comparison
Testcontainers:
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:14");
@Test
void testWithPostgres() {
// Use postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword()
}
Pact JVM:
@Pact(consumer = "ConsumerService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("test state")
.uponReceiving("test request")
.path("/api/resource")
.method("GET")
.willRespondWith()
.status(200)
.body("{\"result\": \"success\"}")
.toPact();
}
Java DSL for easy testing of REST services
Pros of rest-assured
- Simpler setup and easier to get started for API testing
- More intuitive DSL for writing readable test cases
- Broader scope, suitable for general API testing beyond contract testing
Cons of rest-assured
- Lacks built-in contract testing capabilities
- Doesn't generate consumer-driven contracts automatically
- May require additional tools or frameworks for comprehensive contract testing
Code Comparison
rest-assured:
given()
.param("key1", "value1")
.param("key2", "value2")
.when()
.get("/endpoint")
.then()
.statusCode(200)
.body("response.field", equalTo("expectedValue"));
pact-jvm:
@Pact(consumer = "ConsumerName")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("provider state")
.uponReceiving("request description")
.path("/endpoint")
.method("GET")
.willRespondWith()
.status(200)
.body("{\"response\": {\"field\": \"expectedValue\"}}")
.toPact();
}
rest-assured focuses on API testing with a fluent, readable syntax, while pact-jvm specializes in contract testing with a more structured approach to defining interactions between consumers and providers. rest-assured is more versatile for general API testing, but pact-jvm offers robust contract testing capabilities out of the box.
Test Automation Made Simple
Pros of Karate
- All-in-one testing framework for API, UI, performance, and mocks
- Simpler syntax using Gherkin-like DSL, easier for non-programmers
- Built-in reporting and parallel execution capabilities
Cons of Karate
- Less focus on contract testing compared to Pact-JVM
- May require more setup for complex scenarios or integrations
- Limited to JVM languages, while Pact has implementations in multiple languages
Code Comparison
Karate:
Feature: Sample API test
Scenario: Get user details
Given url 'https://api.example.com/users'
And path '1'
When method get
Then status 200
And match response.name == 'John Doe'
Pact-JVM:
@Pact(consumer = "ConsumerService")
public RequestResponsePact createPact(PactDslWithProvider builder) {
return builder
.given("User 1 exists")
.uponReceiving("a request for User 1")
.path("/users/1")
.method("GET")
.willRespondWith()
.status(200)
.body(new PactDslJsonBody().stringValue("name", "John Doe"))
.toPact();
}
Both frameworks offer API testing capabilities, but Karate provides a more readable syntax for non-technical users, while Pact-JVM focuses on contract testing and consumer-driven contracts.
A tool for mocking HTTP services
Pros of WireMock
- More flexible and versatile for general API mocking scenarios
- Supports standalone operation, making it suitable for non-JVM environments
- Offers a rich set of features for request matching and response manipulation
Cons of WireMock
- Requires more setup and configuration compared to Pact JVM
- Doesn't inherently support consumer-driven contract testing
- May be overkill for simple API mocking needs
Code Comparison
WireMock:
stubFor(get(urlEqualTo("/api/resource"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"message\": \"Hello, World!\"}")));
Pact JVM:
builder.uponReceiving("a request for a resource")
.path("/api/resource")
.method("GET")
.willRespondWith()
.status(200)
.headers(Map.of("Content-Type", "application/json"))
.body("{\"message\": \"Hello, World!\"}");
Both libraries allow for API mocking, but WireMock focuses on general-purpose stubbing, while Pact JVM is tailored for consumer-driven contract testing. WireMock offers more flexibility in request matching and response manipulation, making it suitable for complex mocking scenarios. Pact JVM, on the other hand, provides a more streamlined approach to defining and verifying API contracts between consumers and providers.
OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
Pros of openapi-generator
- Supports a wide range of programming languages and frameworks
- Generates client libraries, server stubs, and documentation
- Actively maintained with frequent updates and improvements
Cons of openapi-generator
- Steeper learning curve due to its extensive configuration options
- May generate unnecessary or bloated code for simpler API scenarios
- Requires manual intervention to handle complex data structures or custom logic
Code comparison
openapi-generator:
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/users:
get:
summary: Get users
responses:
'200':
description: Successful response
pact-jvm:
@Pact(consumer = "UserConsumer")
fun getUserPact(builder: PactDslWithProvider): RequestResponsePact {
return builder
.given("users exist")
.uponReceiving("a request for users")
.path("/users")
.method("GET")
.willRespondWith()
.status(200)
.body("{\"users\": []}")
.toPact()
}
While openapi-generator focuses on generating code from API specifications, pact-jvm emphasizes contract testing between consumers and providers. openapi-generator offers broader language support and generates various artifacts, but pact-jvm provides a more targeted approach to ensuring API compatibility between services.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Pact-JVM
JVM implementation of the consumer driven contract library pact.
From the Ruby Pact website:
Define a pact between service consumers and providers, enabling "consumer driven contract" testing.
Pact provides an RSpec DSL for service consumers to define the HTTP requests they will make to a service provider and the HTTP responses they expect back. These expectations are used in the consumers specs to provide a mock service provider. The interactions are recorded, and played back in the service provider specs to ensure the service provider actually does provide the response the consumer expects.
This allows testing of both sides of an integration point using fast unit tests.
This gem is inspired by the concept of "Consumer driven contracts". See https://martinfowler.com/articles/consumerDrivenContracts.html for more information.
Read Getting started with Pact for more information on how to get going.
Contact
- Twitter: @pact_up
- Slack: Join the chat at https://slack.pact.io/
- Stack Overflow: https://stackoverflow.com/questions/tagged/pact
Links
- For examples of using pact-jvm with spring boot, have a look at https://github.com/Mikuu/Pact-JVM-Example and https://github.com/mstine/microservices-pact
Tutorial (60 minutes)
Learn everything in Pact in 60 minutes: https://github.com/pact-foundation/pact-workshop-jvm-spring.
The workshop takes you through all of the key concepts of consumer and provider testing using a Spring boot application.
Documentation
Additional documentation can be found at docs.pact.io, in the Pact Wiki, and in the Pact-JVM wiki. Stack Overflow is also a good source of help, as is the Slack workspace.
Supported JDK and specification versions:
Branch | Specification | JDK | Kotlin Version | Latest Version | Notes |
---|---|---|---|---|---|
4.6.x master | V4 + plugins | 17+ | 1.8.22 | 4.6.13 | |
4.5.x | V4 + plugins | 11+/17+(1) | 1.7.20 | 4.5.12 | |
4.1.x | V3 | 8-12 | 1.3.72 | 4.1.43 |
Notes:
- 1: Spring6 support library requires JDK 17+. The rest of Pact-JVM 4.5.x libs require 11+.
Previous versions (not actively supported)
Branch | Specification | JDK | Kotlin Version | Scala Versions | Latest Version |
---|---|---|---|---|---|
4.4.x | V4 + plugins | 11+ | 1.6.21 | N/A | 4.4.9 |
4.3.x | V4 | 11+ | 1.6.21 | N/A | 4.3.19 |
4.2.x | V4 (1) | 11-15 (2) | 1.4.32 | N/A | 4.2.21 |
4.0.x | V3 | 8-12 | 1.3.71 | N/A | 4.0.10 |
3.6.x | V3 | 8 | 1.3.71 | 2.12 | 3.6.15 |
3.5.x | V3 | 8 | 1.1.4-2 | 2.12, 2.11 | 3.5.25 |
3.5.x-jre7 | V3 | 7 | 1.1.4-2 | 2.11 | 3.5.7-jre7.0 |
2.4.x | V2 | 6 | N/A | 2.10, 2.11 | 2.4.20 |
Notes:
- 1: V4 specification support is only partially implemented with 4.2.x
- 2: v4.2.x may run on JDK 16, but the build for it does not.
NOTE: The JARs produced by this project have changed with 4.1.x to better align with Java 9 JPMS. The artefacts are now:
au.com.dius.pact:consumer
au.com.dius.pact.consumer:groovy
au.com.dius.pact.consumer:junit
au.com.dius.pact.consumer:junit5
au.com.dius.pact.consumer:java8
au.com.dius.pact.consumer:specs2_2.13
au.com.dius.pact:pact-jvm-server
au.com.dius.pact:provider
au.com.dius.pact.provider:scalatest_2.13
au.com.dius.pact.provider:spring
au.com.dius.pact.provider:maven
au.com.dius.pact:provider
au.com.dius.pact.provider:junit
au.com.dius.pact.provider:junit5
au.com.dius.pact.provider:scalasupport_2.13
au.com.dius.pact.provider:lein
au.com.dius.pact.provider:gradle
au.com.dius.pact.provider:specs2_2.13
au.com.dius.pact.provider:junit5spring
au.com.dius.pact.core:support
au.com.dius.pact.core:model
au.com.dius.pact.core:matchers
au.com.dius.pact.core:pactbroker
Service Consumers
Pact-JVM has a number of ways you can write your service consumer tests.
I Use Scala
You want to look at: pact4s.
I Use Java
You want to look at: junit for JUnit 4 tests and junit5 for JUnit 5 tests. Also, if you are using Java 11 or above, there is an updated DSL for consumer tests.
NOTE: If you are using Java 8, there is no separate Java 8 support library anymore, see the above library.
I Use Groovy or Grails
You want to look at: groovy or junit
(Use Clojure I)
Clojure can call out to Java, so have a look at junit. For an example look at example_clojure_consumer_pact_test.clj.
I Use some other jvm language or test framework
You want to look at: Consumer
My Consumer interacts with a Message Queue
As part of the V3 pact specification, we have defined a new pact file for interactions with message queues. For an implementation of a Groovy consumer test with a message pact, have a look at PactMessageBuilderSpec.groovy.
Service Providers
Once you have run your consumer tests, you will have generated some Pact files. You can then verify your service providers with these files.
I am writing a provider and want to ...
verify pacts with SBT
You want to look at: pact4s or scala-pact
verify pacts with Gradle
You want to look at: pact gradle plugin
verify pacts with Maven
You want to look at: pact maven plugin
verify pacts with JUnit tests
You want to look at: junit provider support for JUnit 4 tests and junit5 for JUnit 5 tests
verify pacts with Leiningen
You want to look at: pact leiningen plugin
verify pacts with a Spring MVC project
Have a look at spring or Spring MVC Pact Test Runner (Not maintained).
I want to verify pacts but don't want to use sbt or gradle or leiningen
You want to look at: provider
verify interactions with a message queue
As part of the V3 pact specification, we have defined a new pact file for interactions with message queues. The Gradle pact plugin supports a mechanism where you can verify V3 message pacts, have a look at pact gradle plugin. The JUnit pact library also supports verification of V3 message pacts, have a look at junit.
I Use Ruby or Go or something else
The pact-jvm libraries are pure jvm technologies and do not have any native dependencies.
However, if you have a ruby provider, the json produced by this library is compatible with the ruby pact library. You'll want to look at: Ruby Pact.
For .Net, there is Pact-net.
For JS, there is Pact-JS.
For Go, there is Pact-go.
For Rust, there is Pact-Rust.
Have a look at implementations in other languages.
I Use something completely different
There's a limit to how much we can help, however check out pact-jvm-server
How do I transport my pacts from consumers to providers?
You want to look at: Pact Broker
Which is a project that aims at providing tooling to coordinate pact generation and delivery between projects.
I want to contribute
Documentation for contributors is here.
Test Analytics
We are tracking anonymous analytics to gather important usage statistics like JVM version and operating system. To disable tracking, set the 'pact_do_not_track' system property or environment variable to 'true'.
Top Related Projects
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Java DSL for easy testing of REST services
Test Automation Made Simple
A tool for mocking HTTP services
OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot