Nick Meyer
10/11/2022, 6:10 PMconst { 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:
➜ 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.Matt (pactflow.io / pact-js / pact-go)
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 twoMatt (pactflow.io / pact-js / pact-go)
describe blocksMatt (pactflow.io / pact-js / pact-go)
Matt (pactflow.io / pact-js / pact-go)
jest-pact or mocha-pact to reduce the boilerplateMatt (pactflow.io / pact-js / pact-go)
verify() also resets the test context, removing any expected interactions so any subsequent requests won’t be expectedMatt (pactflow.io / pact-js / pact-go)
Timothy Jones
10/12/2022, 6:29 AMaddInteraction, 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.