Even though my test is passing but the contract is...
# pact-js
s
Even though my test is passing but the contract is not getting created... pact creates a contract in json file after the test has executed??
Copy code
'use strict'

import { setupServer } from 'msw/node'
import { rest } from 'msw'
import { fetchFields } from '../api/index'
import provider from './provider'
import interactions from './interactions/interactions'



describe('fetch fields', () => {
  const expectedBody = { status: true, data: [{ fullName: 'dummy' }] }

  const server = setupServer(
    rest.get(
      `<http://localhost:8992/fields?object_type=dummy>`,
      (req, res, ctx) =>
        res(
          ctx.status(200),
          ctx.json(expectedBody)
        )
    )
  )
  beforeAll(() => server.listen())
  afterEach(() => server.resetHandlers())
  afterAll(() => server.close())

  describe('request to fetch ACE fields', () => {

    beforeAll(async () => {
      await provider.setup();
      await provider.addInteraction(interactions.fetchAceFields);
    });
    test('verify it returns the correct response', async () => {
      const res = await fetchFields("dummy")
      expect(res.data).toEqual(expectedBody)
    })
  })
})
y
you are mocking out the provider calls with msw, but pact should be setup to act as the provider in your test you shouldn’t be using msw, but instead using pact directly to mock out your provider.
You could use msw, with pact-msw-adapter, to convert the msw matches into pact contracts, but you lose out on provider states and matchers so is only suited to bi-directional contract testing https://docs.pactflow.io/docs/bi-directional-contract-testing/tools/msw
s
i made the changes to use pact-msw-adapter.. but it is failing with the below error.. i have strictly follow the example mentioned in the doc..
Copy code
'use strict'

import { setupServer } from 'msw/node';
import { rest } from 'msw';
import { fetchFields } from '../api/index';
import interactions from './interactions/interactions';
import provider from './provider';
import { setupWorker } from "msw";
import {API} from './app'
import { setupPactMswAdapter } from "@pactflow/pact-msw-adapter";
const expectedBody = { status: true, data: [{ fullName: 'dummy' }] }


const server = setupServer(rest.get("<http://localhost:8229>"+"/fields?object_type=dummy", (req, res, ctx) => {
  return res(ctx.status(200), ctx.json(expectedBody));
}));
const pactMswAdapter = setupPactMswAdapter({
  server,
  options: {
    consumer: "webapp",
    providers: {
      ['service']: ['/fields'],
    },
    debug: true,
    includeUrl: ['/fields'],
  },
});
describe('fetch fields', () => {

  beforeAll(async () => {
    server.listen();
  });

  beforeEach(async () => {
    pactMswAdapter.newTest();
  });

  afterEach(async () => {
    pactMswAdapter.verifyTest();
    server.resetHandlers();
  });

  afterAll(async () => {
    await pactMswAdapter.writeToFile();
    pactMswAdapter.clear();
    server.close();
  });

    test('verify it returns the correct response', async () => {  
      const respProducts = await fetchFields("dummy");
      expect(respProducts).toEqual(expectedBody);
    })
})
y
can you either share a full repro or provide the file
import { fetchFields } from '../api/index';
so we can see how your client is configured.
s
i wish i could... i can share the function though
Copy code
export const API = axios.create();
export const fetchFields = (objectType: string) =>
  API.get(`${serviceUrl}/ace-fields?object_type=${objectType}`)
y
You are mocking an endpoint for the path
/fields
Copy code
const server = setupServer(rest.get("<http://localhost:8229>"+"/fields?object_type=dummy", (req, res, ctx) => {
  return res(ctx.status(200), ctx.json(expectedBody));
}));
but your client is using
/ace-fields
Copy code
export const API = axios.create();
export const fetchFields = (objectType: string) =>
  API.get(`${serviceUrl}/ace-fields?object_type=${objectType}`)
How is your
serviceUrl
being set?
s
Do not be concerned about the url. I modified the url in the index.ts file after sending the first message, so I have made the necessary change in the test. serviceUrl comes from.env file
this function is getting called inside useEffect()
y
Your test is incorrect, and not mocking out the correct path. you are also not asserting against the data object from the axios response, but the entire axios response object itself This will generate a Pact. I am concerned with how the url is set, to ensure it is the correct URL you are mocking out, there are cases where using pact-js, you need to be able to override this value during your test, which in your current setup, you wouldn’t be able to, which is why I asked.
Copy code
"use strict";

const setupServer = require("msw/node").setupServer;
const rest = require("msw").rest;
const fetchFields = require("./app").fetchFields;
const setupPactMswAdapter =
  require("@pactflow/pact-msw-adapter").setupPactMswAdapter;
const expectedBody = { status: true, data: [{ fullName: "dummy" }] };

const server = setupServer(
  rest.get(
    "<http://localhost:8229>" + "/fields?object_type=dummy",
    (req, res, ctx) => {
      return res(ctx.status(200), ctx.json(expectedBody));
    }
  )
);
const pactMswAdapter = setupPactMswAdapter({
  server,
  options: {
    consumer: "webapp",
    providers: {
      ["service"]: ["/fields"],
    },
    debug: true,
    includeUrl: ["/fields"],
  },
});
describe("fetch fields", () => {
  beforeAll(async () => {
    server.listen();
  });

  beforeEach(async () => {
    pactMswAdapter.newTest();
  });

  afterEach(async () => {
    pactMswAdapter.verifyTest();
    server.resetHandlers();
  });

  afterAll(async () => {
    await pactMswAdapter.writeToFile();
    pactMswAdapter.clear();
    server.close();
  });

  test("verify it returns the correct response", async () => {
    const respProducts = await fetchFields("dummy");
    expect(respProducts.data).toEqual(expectedBody);
  });
});
app.js
Copy code
const axios = require("axios");
const API = axios.create();
const serviceUrl = "<http://localhost:8229>";
const fetchFields = (objectType) =>
  API.get(`${serviceUrl}/fields?object_type=${objectType}`);

module.exports = {
  API,
  fetchFields,
};
Took 5 mins to create a minimal reproducible example…
y
s
I'm sorry I wasn't aware of this. will certainly create a minimal reproducible sample from the next time...
y
It’s ok matey, and thank you, it is the best way to get support without the to and fro 🙂 I’ve updated the repro with a working example using pact-msw-adapter, and pact-js, both with the new v3 interface and with the old v2 interface. Good luck in your Pact journey
s
Thanks 🤗