Convert Figma logo to code with AI

pact-foundation logopact-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.

1,077
478
1,077
356

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

8,079

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

  1. 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();
}
  1. 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
    }
}
  1. 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:

  1. 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>
  1. Write consumer tests defining the expected interactions.
  2. Generate Pact files from consumer tests.
  3. Implement provider tests to verify the Pact contracts.
  4. 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.

8,079

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Pact-JVM

Pact-JVM Build Maven Central

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

Links

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:

BranchSpecificationJDKKotlin VersionLatest VersionNotes
4.6.x masterV4 + plugins17+1.8.224.6.13
4.5.xV4 + plugins11+/17+(1)1.7.204.5.12
4.1.xV38-121.3.724.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)

BranchSpecificationJDKKotlin VersionScala VersionsLatest Version
4.4.xV4 + plugins11+1.6.21N/A4.4.9
4.3.xV411+1.6.21N/A4.3.19
4.2.xV4 (1)11-15 (2)1.4.32N/A4.2.21
4.0.xV38-121.3.71N/A4.0.10
3.6.xV381.3.712.123.6.15
3.5.xV381.1.4-22.12, 2.113.5.25
3.5.x-jre7V371.1.4-22.113.5.7-jre7.0
2.4.xV26N/A2.10, 2.112.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'.