John Walker
John Walker

Reputation: 543

How do I get a basic example of a pact test working with TypeScript and Mocha

I am having issues running a demo pact test which basically a copy of: an example from pact-js. I have made only minimal modifications to convert the example to TypeScript.

When I run the tests mocha --require ts-node/register ./src/test/**.test.ts from either yarn2 or npm I get the following errors:

 1) Pact between MyConsumer and MyProvider
       with 30000 ms timeout for Pact
         get /dogs
           returns the correct response:
     Error: connect ECONNREFUSED ::1:8992
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1158:16)    

  2) Pact between MyConsumer and MyProvider
       with 30000 ms timeout for Pact
         "after each" hook: MochaPactVerifyAfterEach for "returns the correct response":
     Error: Pact verification failed - expected interactions did not match actual.                

From the error it looks like the connection to the pact provider is failing but how can this be fixed?

The two main files are as follows:

indexMocha.ts

import axios from "axios"

type DogParams = {
  url: string,
  port: number
}

export const getMeDogs = (endpoint: DogParams) => {
  const
    url = endpoint.url,
    port = endpoint.port

  return axios.request({
    method: "GET",
    baseURL: `${url}:${port}`,
    url: "/dogs",
    headers: { Accept: "application/json" },
  })
}

export const getMeDog = (endpoint: DogParams) => {
  const
    url = endpoint.url,
    port = endpoint.port

  return axios.request({
    method: "GET",
    baseURL: `${url}:${port}`,
    url: "/dogs/1",
    headers: { Accept: "application/json" },
  })
}

getDogMocha.test.ts

const expect = require("chai").expect
import { InteractionObject } from "@pact-foundation/pact"
import { pactWith } from "mocha-pact"
import { getMeDogs, getMeDog } from "../lib/indexMocha"

const port = 8992

pactWith(
  {
    port,
    consumer: "MyConsumer",
    provider: "MyProvider",
  },
  provider => {
    let url = "http://localhost"

    const EXPECTED_BODY = [
      {
        dog: 1,
      },
      {
        dog: 2,
      },
    ]

    describe("get /dogs", () => {
      before(done => {
        const interaction: InteractionObject = {
          state: "i have a list of dogs",
          uponReceiving: "a request for all dogs",
          withRequest: {
            method: "GET",
            path: "/dogs",
            headers: {
              Accept: "application/json",
            },
          },
          willRespondWith: {
            status: 200,
            headers: {
              "Content-Type": "application/json",
            },
            body: EXPECTED_BODY,
          },
        }
        provider.addInteraction(interaction).then(() => {
          done()
        })
      })

      it("returns the correct response", done => {
        const urlAndPort = {
          url: url,
          port: port,
        }
        getMeDogs(urlAndPort).then(response => {
          expect(response.data).to.eql(EXPECTED_BODY)
          done()
        }, done)
      })
    })

    describe("get /dog/1", () => {
      before(done => {
        const interaction: InteractionObject = {
          state: "i have a list of dogs",
          uponReceiving: "a request for a single dog",
          withRequest: {
            method: "GET",
            path: "/dogs/1",
            headers: {
              Accept: "application/json",
            },
          },
          willRespondWith: {
            status: 200,
            headers: {
              "Content-Type": "application/json",
            },
            body: EXPECTED_BODY,
          },
        }
        provider.addInteraction(interaction).then(() => {
          done()
        })
      })

      it("returns the correct response", done => {
        const urlAndPort = {
          url: url,
          port: port,
        }
        getMeDog(urlAndPort).then(response => {
          expect(response.data).to.eql(EXPECTED_BODY)
          done()
        }, done)
      })
    })
  }
)

Upvotes: 0

Views: 478

Answers (1)

Matthew Fellows
Matthew Fellows

Reputation: 4065

Thanks for creating a repro - unfortunately on my macbook OSX (10.15.7) it works just fine:

  Pact between MyConsumer and MyProvider
    with 30000 ms timeout for Pact
      get /dogs
        ✔ returns the correct response
      get /dog/1
        ✔ returns the correct response


  2 passing (7s)

➜  pact-play git:(main) ✗

There could be a few things here. First, please follow the debugging tips to share debug level logs - this will help us see what is going on.

There are other common issues to investigate there also.

One last thought, based on the error, it could be an ipv6 issue. Could you please try binding explicitly to an address (not a hostname). e.g. 127.0.0.1

Upvotes: 2

Related Questions