pact-js-mocha

1.0.2-alpha • Public • Published

Pact Mocha Interface

Build Status Code Climate Issue Count Coverage Status npm

Implementation of a Mocha Interface to be used with pact-js.

From the Pact website:

The Pact family of frameworks provide support for Consumer Driven Contracts testing.

A Contract is a collection of agreements between a client (Consumer) and an API (Provider) that describes the interactions that can take place between them.

Consumer Driven Contracts is a pattern that drives the development of the Provider from its Consumers point of view.

Pact is a testing tool that guarantees those Contracts are satisfied.

Read Getting started with Pact for more information on how to get going.

How to use it

This package is not yet published to NPM so you will need to install it manually by modifying your package.json.

Installation

It's easy, simply run:

npm install --save-dev pact-js-mocha

What does this interface does

This Mocha interface abstracts some aspects of the usage of the DSL to make your test a bit cleaner and not having to worry about learning the Pact JS DSL.

We thought it was useful due to the fact that there is some boilerplate code needed to get the DSL up and going so abstracting all this made sense.

In a nutshell:

  • Provides two top level Pact() and PactProvider() block that works like a describe() block but with extra init functionality for Pact
  • Starts up a Pact Mock Server for you
  • Does the verification for you sending back the response of the request for your own assertions
  • Clean up all state and shuts down the mock servers created

Usage

The interface "extends" the Mocha BDD so all the original hooks still work as expected thus you don't have to mix and match your test runs.

Once the library is installed you have to tell Mocha to use it. To do that you can either create a mocha.opts file on your test folder and tell Mocha to use it, like this:

--require ./node_modules/pact-js-mocha/src/index.js
For Consumers only

You also have to tell Mocha to start the Pact Mock Server. The management of the Mock Server is up to you: you can either manage within the test file itself or as part of your test suite.

The example below shows how you can do the latter. To manage within your test suite have a look at this integration test on the Pact JS library itself.

To do that create a new file inside your test folder named specHelper.js and add the below to it:

var path = require('path')
var wrapper = require('@pact-foundation/pact-node')
 
// create mock server to listen on port 1234
var mockServer = wrapper.createServer({
  port: 1234,
  log: path.resolve(process.cwd(), 'logs', 'mockserver-ui.log'),
  dir: path.resolve(process.cwd(), 'pacts'),
  spec: 2
})
 
// start the mock server
mockServer.start().then(function () {
  // runs Mocha's test suite
  run()
})

Finally you need to also tell Mocha to require specHelper.js and delay the execution. Your final set of arguments will look like this:

--require ./node_modules/pact-js-mocha/src/index.js
--require ./test/specHelper.js
--delay

That's it. Then you can write your consumer test like below:

var expect = require('chai').expect
var request = require('superagent')
 
var PactOpts = {
  consumer: 'PactUI',             // the name of your consumer
  provider: 'Projects Provider',  // the name of your Provider
  providerPort: 1234              // the port on which the provider runs
}
 
PactConsumer(PactOpts, function () {
 
  // this is wrapped in a before() block
  // it takes an Array of interactions
  addInteractions([{
    state: 'i have a list of projects',
    uponReceiving: 'a request for projects',
    withRequest: {
      method: 'get',
      path: '/projects',
      headers: { 'Accept': 'application/json' }
    },
    willRespondWith: {
      status: 200,
      headers: { 'Content-Type': 'application/json; charset=utf-8' },
      body: { reply: 'hello' }
    }
  }])
 
  function requestProjects () {
    return request.get('http://localhost:' + PactOpts.providerPort + '/projects').set({ 'Accept': 'application/json' })
  }
 
  // this is your 'it' block
  verify('a list of projects is returned', requestProjects, function (result, done) {
    expect(JSON.parse(result)).to.eql({ reply: 'hello' })
    done()
  })
 
  // this is wrapped in a after block
  // thus it runs after all your verify's
  // it writes the pact and clear all interactions
  finalizePact()
 
})

And your provider test will look like this (there's no need to tell Mocha about the Mock Server):

var expect = require('chai').expect
 
PactProvider({consumer: 'Projects Consumer', provider: 'Projects Provider'}, function () {
 
  var pactOpts = {
    providerBaseUrl: 'http://my.provider.com',
    pactUrls: '/path/to/pact_file.json',
    providerStatesUrl: 'http://my.provider.com/providerStates',
    providerStatesSetupUrl: 'http://my.provider.com/setupProviderStates',
  }
 
  honourPact(pactOpts, function (result, done) {
    done()
  })
 
})

Contact

Package Sidebar

Install

npm i pact-js-mocha

Weekly Downloads

3

Version

1.0.2-alpha

License

MIT

Last publish

Collaborators

  • mboudreau
  • mfellows
  • tarcio