Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing arguments with toBeCalledWith() in Jest

I have function that uses puppetteer's page object to evaluate and return some data.

I would like to write a unit test with jest to check if page.evaluate() takes specified parameters

This is the function

async function cinemasfromState(page, state) {
  const CINEMA_SELECTOR = `div[data-state=$[STATE]] div.top-select-option a.eccheckbox`;
  let res = await page.evaluate(
    (elementPath, state) => {
      let results = Array.from(document.querySelectorAll(elementPath)).map(
        function(cin, index) {
          return {
            //Stuff
          };
          return result;
        },
        { state }
      );
    },
    CINEMA_SELECTOR.replace("$[STATE]", state),
    state
  );

  return res;
}

Below is what my test looks like

describe("cinemasfromState", () => {
  let page_mock = {
    click: jest.fn(() => Promise.resolve()),
    evaluate: jest.fn((selector, state) => Promise.resolve())
  };

  test("page.evaluate called correctly ", async () => {
    await cinemasfromState(page_mock, "KAN");
    expect(page_mock.evaluate).toBeCalledTimes(1);
    expect(
      page_mock.evaluate)toBeCalledWith(
        "div[data-state=KAN] div.top-select-option a.eccheckbox",
        "KAN"
      );
  });
});

And I get the below error as my test output

● cinemasfromState › page.evaluate called correctly

    expect(jest.fn()).toBeCalledWith(expected)

    Expected mock function to have been called with:
      "div[data-state=KAN] div.top-select-option a.eccheckbox"
    as argument 1, but it was called with
      [Function anonymous].

    Difference:

      Comparing two different types of values. Expected string but received function.
      "KAN"
    as argument 2, but it was called with
      "div[data-state=KAN] div.top-select-option a.eccheckbox".
      undefined
    as argument 3, but it was called with
      "KAN".

    Difference:

      Comparing two different types of values. Expected undefined but received string.

      52 |     expect(page_mock1.evaluate).toBeCalledTimes(1);
      53 |     expect(page_mock1.evaluate).toBeCalledWith(
    > 54 |       "div[data-state=KAN] div.top-select-option a.eccheckbox",
         |                            ^
      55 |       "KAN"
      56 |     );
      57 |   });

Any help on writing test to verify the arguments?

like image 745
Theepan Thevathasasn Avatar asked Nov 11 '18 05:11

Theepan Thevathasasn


People also ask

What is Jest fn () do?

The jest. fn method allows us to create a new mock function directly. If you are mocking an object method, you can use jest. spyOn . And if you want to mock a whole module, you can use jest.

How do you use spyOn function in Jest?

To spy on an exported function in jest, you need to import all named exports and provide that object to the jest. spyOn function. That would look like this: import * as moduleApi from '@module/api'; // Somewhere in your test case or test suite jest.

Which assertion used to test a value is with exact equality in Jest?

Common Matchers​ The simplest way to test a value is with exact equality.


1 Answers

If you read your error log, you'll notice it's trying to match three arguments, but you are only asserting against two. .toBeCalledWith in jest will perform an exact match of the arguments passed to the function along with their order.

For instance, if you call func(arg1, arg2), then expect(func).toBeCalledWith(arg2) will fail because you did not also assert on arg1. This is what is happening in your case because the first argument to page.evaluate() is actually an anonymous function.

So, your test will need to be something like this:

expect(page_mock.evaluate).toBeCalledWith(
  expect.any(Function),
  "div[data-state=KAN] div.top-select-option a.eccheckbox",
  "KAN"
);
like image 144
Auroratide Avatar answered Oct 10 '22 06:10

Auroratide