Hi I'm having trouble with Pact mock server - it l...
# pact-js
v
Hi I'm having trouble with Pact mock server - it looks to be configured as in the manual, but from logs it looks like it starts and then shuts down:
Copy code
[09:38:07] :	 [Step 1/1] 2022-10-27T09:38:07.687602Z DEBUG ThreadId(01) pactffi_create_mock_server_for_pact{pact=PactHandle { pact_ref: 2 } addr_str=0x7ffceb12faf0 tls=false}: pact_mock_server::mock_server: Started mock server on 127.0.0.1:34851
[09:38:07] :	 [Step 1/1] 2022-10-27T09:38:07.692042Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
[09:38:07] :	 [Step 1/1] 2022-10-27T09:38:07.692066Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID 669f159b-22ac-4e8d-b0c6-378f489ba070 - MockServerMetrics { requests: 0 }
[09:38:07] :	 [Step 1/1] 2022-10-27T09:38:07.692087Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server 669f159b-22ac-4e8d-b0c6-378f489ba070 shutdown - MockServerMetrics { requests: 0 }
[09:38:07] :	 [Step 1/1] 2022-10-27T09:38:07.692105Z DEBUG tokio-runtime-worker hyper::server::shutdown: signal received, starting graceful shutdown
Attached is test code (I've removed some tests for readability as they have same logic) and build logs. Could you please help with this?
ok, seems like the issue was with test not being async - after changes, it started to work
y
Copy code
const path = require("path");
const request = require("superagent");
const { PactV3 } = require("@pact-foundation/pact");
const chai = require("chai");
const expect = chai.expect;

const { integer, timestamp, boolean, string, eachLike, like, reify } =
  require("@pact-foundation/pact").MatchersV3;

const tenantId = "acme";
const projectId = "agcstest";

const authHeader = {
  Authorization: "Bearer token"
};

const getBackupsListUrl = `/api/v3/databases/backups/${tenantId}/${projectId}`;

const backupsListExpectedBody = eachLike({
  id: like(1),
  name: like("string"),
  type: like("string"),
  startedAt: like("timestamp"),
  completedAt: like("timestamp"),
  sourceProjectId: like("string"),
  sourceEnvironmentId: like("string"),
  tenantId: like("string"),
  projectId: like("string")
});
describe("Pact", () => {
  const provider = new PactV3({
    dir: path.resolve(process.cwd(), "pacts"),
    consumer: "DatabaseServiceUI",
    provider: "DatabaseService",
    logLevel: "debug"
  });

  describe("GET to database backups list", () => {
    it("returns list of DB backups", () => {
      provider
        .given(`GET to ${getBackupsListUrl}`)
        .uponReceiving("request to list all DB backups")
        .withRequest({
          method: "GET",
          path: getBackupsListUrl
        })
        .willRespondWith({
          status: 200,
          body: backupsListExpectedBody
        });

      return provider.executeTest((mockserver) => {
        return request
          .get(mockserver.url + getBackupsListUrl)
          .set(authHeader)
          .then((res) => {
            expect(res.body).to.have.deep.members(
              reify(backupsListExpectedBody)
            );
          });
      });
    });
  });
});
had a quick look. this is using mocha/chai. 1. you have matchers in your expected payload, in your
expect(res.body).toMatchObject(backupsListExpectedBody);
- you can use the
reify
method to strip the matchers off the body, otherwise you are expected your api client to return you an object with pact matchers 2. Your
like
matcher needs to have a valid value,
string
is not defined
like("example string to add into the example")
will match any string. so not
like(string)
unless you have
string
declared as a string value
const string = "some example value"
3. You can wrap the
backupsListExpectedBody
object, in an
eachLike
matcher, which will say match me an array with at least 1 of these shape objects in.
generated pact file
Copy code
{
  "consumer": {
    "name": "DatabaseServiceUI"
  },
  "interactions": [
    {
      "description": "request to list all DB backups",
      "providerStates": [
        {
          "name": "GET to /api/v3/databases/backups/acme/agcstest"
        }
      ],
      "request": {
        "method": "GET",
        "path": "/api/v3/databases/backups/acme/agcstest"
      },
      "response": {
        "body": [
          {
            "completedAt": "timestamp",
            "id": 1,
            "name": "string",
            "projectId": "string",
            "sourceEnvironmentId": "string",
            "sourceProjectId": "string",
            "startedAt": "timestamp",
            "tenantId": "string",
            "type": "string"
          }
        ],
        "headers": {
          "Content-Type": "application/json"
        },
        "matchingRules": {
          "body": {
            "$": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].completedAt": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].id": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].name": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].projectId": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].sourceEnvironmentId": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].sourceProjectId": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].startedAt": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].tenantId": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$[*].type": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "status": 200
      }
    }
  ],
  "metadata": {
    "pact-js": {
      "version": "10.1.4"
    },
    "pactRust": {
      "ffi": "0.3.12",
      "models": "0.4.5"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "DatabaseService"
  }
}
thanks for the test file 👍
v
Thank you @Yousaf Nabi (pactflow.io) just a qq - is there any way to use type matchers in JS?
y
https://github.com/pact-foundation/pact-js/blob/master/docs/matching.md this might help buddy, not sure on the exact question, this will do type matching based on the example value you add in, so it infers the type.
v
thanks!