Testing what was supposed to be a quick and easy d...
# pact-js
n
Testing what was supposed to be a quick and easy demo out… can anyone tell me why this doesn’t work?
Copy code
const { Pact } = require("@pact-foundation/pact");

const apiProvider = new Pact({
  consumer: "webapp",
  provider: "api",
});

describe("pact", () => {
  beforeAll(async () => { 
    await apiProvider.setup()
    await apiProvider.addInteraction({
      state: "arriving",
      uponReceiving: "greeting",
      withRequest: {
        method: "GET",
        path: "/hello",
      },
      willRespondWith: {
        status: 200,
        headers: { "Content-Type": "text/plain" },
        body: "hello"
      }
    })
    await apiProvider.addInteraction({
      state: "departing",
      uponReceiving: "farewell",
      withRequest: {
        method: "GET",
        path: "/goodbye",
      },
      willRespondWith: {
        status: 200,
        headers: { "Content-Type": "text/plain" },
        body: "goodbye"
      }
    })
  });

  afterAll(() => apiProvider.finalize());
  afterEach(() => apiProvider.verify());

  it("says hello", async () => {
    const greeting = await (await fetch(`${apiProvider.mockService.baseUrl}/hello`)).text();
    expect(greeting).toBe("hello");
  });

  it("says goodbye", async () => {
    const farewell = await (await fetch(`${apiProvider.mockService.baseUrl}/goodbye`)).text();
    expect(farewell).toBe("goodbye")
  });
})
Output:
Copy code
➜  pact npm test

> pacter@1.0.0 test
> jest

[2022-10-11 18:08:10.521 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact-node@10.17.6: Creating Pact Server with options: 
{"timeout":30000,"consumer":"webapp","cors":false,"dir":"/private/tmp/pact/pacts","host":"127.0.0.1","log":"/private/tmp/pact/logs/pact.log","logLevel":"INFO","pactfileWriteMode":"overwrite","provider":"api","spec":2,"ssl":false,"pactFileWriteMode":"overwrite"}
[2022-10-11 18:08:10.928 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact-node@10.17.6: Pact running on port 59384
[2022-10-11 18:08:11.046 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact@9.18.1: Setting up Pact with Consumer "webapp" and Provider "api"
    using mock service on Port: "59384"
(node:86870) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
[2022-10-11 18:08:11.074 +0000] ERROR (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact@9.18.1: error making http request: Request failed with status code 500
  console.error
    

      at node_modules/@pact-foundation/src/httpPact.ts:151:17

  console.error
    Pact verification failed!

      at node_modules/@pact-foundation/src/httpPact.ts:152:17

  console.error
    Actual interactions do not match expected interactions for mock MockService.
    
    Missing requests:
        GET /goodbye
    
    
    See /private/tmp/pact/logs/pact.log for details.
    

      at node_modules/@pact-foundation/src/httpPact.ts:153:17

[2022-10-11 18:08:11.100 +0000] ERROR (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact@9.18.1: error making http request: Request failed with status code 500
  console.error
    

      at node_modules/@pact-foundation/src/httpPact.ts:151:17

  console.error
    Pact verification failed!

      at node_modules/@pact-foundation/src/httpPact.ts:152:17

  console.error
    Actual interactions do not match expected interactions for mock MockService.
    
    Unexpected requests:
        GET /goodbye
    
    
    See /private/tmp/pact/logs/pact.log for details.
    

      at node_modules/@pact-foundation/src/httpPact.ts:153:17

[2022-10-11 18:08:11.108 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact@9.18.1: Pact File Written
[2022-10-11 18:08:11.108 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact-node@10.17.6: Removing Pact process with PID: 86906
[2022-10-11 18:08:11.109 +0000] INFO (86870 on <http://FTPHXMMV4R.dyn.ourparadisefalls.com|FTPHXMMV4R.dyn.ourparadisefalls.com>): pact-node@10.17.6: Deleting Pact Server with options: 
{"timeout":30000,"consumer":"webapp","cors":false,"dir":"/private/tmp/pact/pacts","host":"127.0.0.1","log":"/private/tmp/pact/logs/pact.log","logLevel":"INFO","pactfileWriteMode":"overwrite","provider":"api","spec":2,"ssl":false,"port":59384,"pactFileWriteMode":"overwrite"}
 FAIL  ./index.test.js
  pact
    ✕ says hello (31 ms)
    ✕ says goodbye (10 ms)

  ● pact › says hello

    Pact verification failed - expected interactions did not match actual.

      at new VerificationError (node_modules/@pact-foundation/pact/src/errors/verificationError.js:19:42)
      at node_modules/@pact-foundation/src/httpPact.ts:157:17

  ● pact › says goodbye

    expect(received).toBe(expected) // <http://Object.is|Object.is> equality

    - Expected  - 1
    + Received  + 2

    - goodbye
    + {"message":"No interaction found for GET /goodbye","interaction_diffs":[]}
    +

      47 |   it("says goodbye", async () => {
      48 |     const farewell = await (await fetch(`${apiProvider.mockService.baseUrl}/goodbye`)).text();
    > 49 |     expect(farewell).toBe("goodbye")
         |                      ^
      50 |   });
      51 | })

      at Object.toBe (index.test.js:49:22)

  ● pact › says goodbye

    Pact verification failed - expected interactions did not match actual.

      at new VerificationError (node_modules/@pact-foundation/pact/src/errors/verificationError.js:19:42)
      at node_modules/@pact-foundation/src/httpPact.ts:157:17

Test Suites: 1 failed, 1 total
Tests:       2 failed, 2 total
Snapshots:   0 total
Time:        1.127 s, estimated 2 s
Ran all test suites.
For some reason, the mock server never seems to pick up the “goodbye” interaction. The interesting thing is… it doesn’t matter if I swap the order of the interactions, it’s still the “goodbye” one that isn’t expected.
m
The issue is the
afterEach
block is verifying that the calls are made after each individual
it
block. Given you setup 2 interactions, the
provider.verify()
will be called after one of the
it
blocks, and will fail because it expects two
The requests aren’t linked, so separate them out into separate
describe
blocks
Take a look at https://github.com/pact-foundation/pact-js/blob/master/examples/e2e/test/consumer.spec.js which has a number of different tests, you can see they are split out
you could also look at using
jest-pact
or
mocha-pact
to reduce the boilerplate
verify()
also resets the test context, removing any expected interactions so any subsequent requests won’t be expected
if you can share the log file we can validate it for certain, but the test setup is out of whack
t
^ This is all correct. When you
addInteraction
, you're actually setting up the test expectation, not describing a mock server. So if that expectation is not met, then the test will fail.