To allow the correct data to be set up before each interaction is replayed, you will need to create an HTTP endpoint (which may or may not actually be in the same application as your provider) that accepts a JSON document describing the state. The exact format of this document depends on whether you are using the JVM implementation, or one of the wrapped Ruby implementations (effectively everything that isn't JVM).
The endpoint should set up the given provider state for the given consumer synchronously, and return an error if the provider state is not recognised. Namespacing your provider states within each consumer will avoid clashes if more than one consumer defines the same provider state with different data.
See the pact-provider-verifier documentation for the exact details of implementing a provider-states-setup-url.
To define service provider states that create the right data for the provider states described above, write the following in the service provider project. (The consumer name here must match the name of the consumer configured in your consumer project for it to correctly find these provider states.)
# In /spec/service_consumers/provider_states_for_my_service_consumer.rb
Pact.provider_states_for 'My Service Consumer' do
provider_state "a thing exists" do
set_up do
# Create a thing here using your framework of choice
# eg. Sequel.sqlite[:somethings].insert(name: "A small something")
end
tear_down do
# Any tear down steps to clean up the provider state
end
end
provider_state "a thing does not exist" do
no_op # If there's nothing to do because the state name is more for documentation purposes,
# you can use no_op to imply this.
end
end
Require your provider states file in the pact_helper.rb
To define code that should run before/after each interaction for a given consumer, regardless of whether a provider state is specified or not, define set_up/tear_down blocks with no wrapping provider_state.
Pact.provider_states_for 'My Service Consumer' do
set_up do
# This will run before the set_up for provider state specified for the interaction.
# eg. create API user, set the expected basic auth details
end
tear_down do
# ...
# This will run after the tear_down for the specified provider state.
Global state will be set up before consumer specific base state. Avoid using the global set up for creating data as it will make your tests brittle when more than one consumer exists.
In Pact specification v3 and later, multiple provider states may be defined for an interaction, and each provider state has params, as well as a name. If you are verifying a v3 pact, and you are using version 1.36.0 or later of the pact gem, you can access the provider state params via the block arguments in the set up or tear down code.
Including modules for use in set_up and tear_down#
Any modules included this way will be available in the set_up and tear_down blocks. One common use of this to include factory methods for setting up data so that the provider states file doesn't get too bloated.