Javascript – How to mock the JavaScript window object using Jest

javascriptjestjsmocking

I need to test a function which opens a new tab in the browser

openStatementsReport(contactIds) {
  window.open(`a_url_${contactIds}`);
}

I would like to mock the window's open function so I can verify the correct URL is passed in to the open function.

Using Jest, I don't know how to mock the window. I tried to set window.open with a mock function but this way doesn't work. Below is the test case

it('correct url is called', () => {
  window.open = jest.fn();
  statementService.openStatementsReport(111);
  expect(window.open).toBeCalled();
});

But it gives me the error

expect(jest.fn())[.not].toBeCalled()

jest.fn() value must be a mock function or spy.
    Received:
      function: [Function anonymous]

What should I do to the test case?

Best Answer

The following method worked for me. This approach allowed me to test some code that should work both in the browser and in Node.js, as it allowed me to set window to undefined.

This was with Jest 24.8 (I believe):

let windowSpy;

beforeEach(() => {
  windowSpy = jest.spyOn(window, "window", "get");
});

afterEach(() => {
  windowSpy.mockRestore();
});

it('should return https://example.com', () => {
  windowSpy.mockImplementation(() => ({
    location: {
      origin: "https://example.com"
    }
  }));

  expect(window.location.origin).toEqual("https://example.com");
});

it('should be undefined.', () => {
  windowSpy.mockImplementation(() => undefined);

  expect(window).toBeUndefined();
});