<commit_before># Pact

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 http://martinfowler.com/articles/consumerDrivenContracts.html for more information.

Travis CI Status: [![travis-ci.org Build Status](https://travis-ci.org/realestate-com-au/pact.png)](https://travis-ci.org/realestate-com-au/pact)

## Features
* A service is mocked using an actual process running on a specified port, so javascript clients can be tested as easily as backend clients.
* "Provider states" (similar to fixtures) allow the same request to be made with a different expected response.
* Consumers specify only the fields they are interested in, allowing a provider to return more fields without breaking the pact. This allows a provider to have a different pact with a different consumer, and know which fields each cares about in a given response.
* Expected interactions are verified to have actually occurred in the consumer specs.
* The mocked responses are verified to be valid by replaying the interactions against the provider codebase.
* Rake verification tasks allow a pacts at one or more URIs to be checked against a given service provider codebase.
* Different versions of a consumer/provider pair can be easily tested against each other, allowing confidence when deploying new versions of each (see the pact_broker and pact_broker-client gems).

## How does it work?

1. In the specs for the provider facing code in the consumer project, expectations are set up on a mock service provider.
1. When the specs are run, the requests, and their expected responses, are written to a "pact" file.
1. The requests in the pact file are later replayed against the provider, and the actual responses are checked to make sure they match the expected responses.

## Why is developing and testing with pacts better than using integration tests?

* Faster execution.
* No need to manage starting and stopping multiple processes.
* Reliable responses from mock service provider reduce likelihood of flakey tests.
* Only one component is being tested at a time, making the causes of test failures easier to identify.
* Design of service provider is improved by considering first how the data is actually going to be used, rather than how it is most easily retrieved and serialised.

## Installation

Put it in your Gemfile. You know how.

## Usage

### Service Consumer project

#### 1. Start with you model

Imagine a model class that looks something like this. The attributes for a SomethingModel live on a remote server, and will need to be retrieved by an HTTP call.

```ruby
class SomethingModel
  attr_reader :name

  def intialize name
    @name = name
  end

  def == other
    other.is_a?(Something) && other.name == name
  end
end
```

#### 2. Create a skeleton client class

Imagine a service provider client class that looks something like this.<commit_msg>Fixed SomethingModel example code.<commit_after># Pact

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 http://martinfowler.com/articles/consumerDrivenContracts.html for more information.

Travis CI Status: [![travis-ci.org Build Status](https://travis-ci.org/realestate-com-au/pact.png)](https://travis-ci.org/realestate-com-au/pact)

## Features
* A service is mocked using an actual process running on a specified port, so javascript clients can be tested as easily as backend clients.
* "Provider states" (similar to fixtures) allow the same request to be made with a different expected response.
* Consumers specify only the fields they are interested in, allowing a provider to return more fields without breaking the pact. This allows a provider to have a different pact with a different consumer, and know which fields each cares about in a given response.
* Expected interactions are verified to have actually occurred in the consumer specs.
* The mocked responses are verified to be valid by replaying the interactions against the provider codebase.
* Rake verification tasks allow a pacts at one or more URIs to be checked against a given service provider codebase.
* Different versions of a consumer/provider pair can be easily tested against each other, allowing confidence when deploying new versions of each (see the pact_broker and pact_broker-client gems).

## How does it work?

1. In the specs for the provider facing code in the consumer project, expectations are set up on a mock service provider.
1. When the specs are run, the requests, and their expected responses, are written to a "pact" file.
1. The requests in the pact file are later replayed against the provider, and the actual responses are checked to make sure they match the expected responses.

## Why is developing and testing with pacts better than using integration tests?

* Faster execution.
* No need to manage starting and stopping multiple processes.
* Reliable responses from mock service provider reduce likelihood of flakey tests.
* Only one component is being tested at a time, making the causes of test failures easier to identify.
* Design of service provider is improved by considering first how the data is actually going to be used, rather than how it is most easily retrieved and serialised.

## Installation

Put it in your Gemfile. You know how.

## Usage

### Service Consumer project

#### 1. Start with you model

Imagine a model class that looks something like this. The attributes for a SomethingModel live on a remote server, and will need to be retrieved by an HTTP call.

```ruby
class SomethingModel
  attr_reader :name

  def initialize name
    @name = name
  end

  def == other
    other.is_a?(SomethingModel) && other.name == name
  end
end
```

#### 2. Create a skeleton client class

Imagine a service provider client class that looks something like this.
{'fraction_non_alphanumeric': 0.045578720345075485, 'fraction_numerical': 0.0014378145219266715, 'mean_word_length': 4.447141738449491, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6972787', 'n_tokens_mistral': 1668, 'n_tokens_neox': 1593, 'n_words': 1024}