3

We've been trying to test an API exposed from a microservice (say GET /contacts) which is being consumed by another microservice.

In order to avoid integration tests, we created consumer-driven contract tests where the consumer microservice created pacts and published them to a broker from where the producer would verify the pact separately.

We've used Pact IO to achieve this and it has been quite good so far.

Now we are facing issues when trying to do exhaustive tests where we would want to see how an empty list is returned from GET /contacts.

The problem is: while adding interactions, we could use Provider States but we couldn't find a way to differentiate between writing tests for getting a list of contacts from GET /contacts once and getting an empty list in another test.

This is how we create pact tests in our consumer microservice:

mockServer.start()
        .then(() => {
          provider = pact({
            // config
          })
          return provider.addInteraction({
            state: 'Get all contacts',
            uponReceiving: 'Get all contacts',
            withRequest: {
              method: 'GET',
              path: '/contacts',
              headers: {
                Accept: 'application/json; charset=utf-8'
              }
            },
            willRespondWith: {
              status: 200,
              body: //list of all contacts
            }
          })
        .then(() => {
          return provider.addInteraction({
            state: 'Get empty list of contacts',
            uponReceiving: 'Get empty list of contacts',
            withRequest: {
              method: 'GET',
              path: '/contacts',
              headers: {
                Accept: 'application/json; charset=utf-8'
              }
            },
            willRespondWith: {
              status: 200,
              body: [] // empty list
            }
          })
        })

We cannot find a way to differentiate between these interations in our tests! :(

Any help would be appreciated!

Thanks.

Hawkes
  • 457
  • 1
  • 4
  • 16

1 Answers1

2

Assume you're using something like Mocha, you should separate these interactions into individual tests - e.g. call addInteraction in each describe block that's contextual to the test case you're running (possibly in the before to make your tests clearer).

Your general structure might look like the below (pseudo-code):

context("Contacts exist")
  describe("call some API")
    before()
      provider.addInteraction(interactionWithContacts)

    it("Returns a list of contact objects")
      # your test code here
      # Verify - this will also clear interactions so
      # your next test won't conflict 
      provider.verify()

context("No contacts exist")
  describe("call some API")
    before()
      provider.addInteraction(interactionWithNoContacts)

    it("Returns an empty list of contacts")
      # your test code here
      # Verify - this will also clear interactions so
      # your next test won't conflict 
      provider.verify()       
Matthew Fellows
  • 3,669
  • 1
  • 15
  • 18