如何使用Jest模拟JavaScript的“窗口”对象?

2022-08-30 01:34:16

我需要测试一个在浏览器中打开新选项卡的函数

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

我想模拟窗口的函数,这样我就可以验证正确的URL是否传递给函数。openopen

使用Jest,我不知道如何嘲笑。我试图用模拟函数进行设置,但这种方式不起作用。下面是测试用例:windowwindow.open

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

但它给了我错误

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

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

我应该对测试用例执行哪些操作?


答案 1

以下方法对我有用。这种方法允许我测试一些应该在浏览器和Node.js中都工作的代码,因为它允许我设置为。windowundefined

这是在Jest 24.8(我相信):

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();
});

答案 2

而不是 ,请使用 :windowglobal

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

您还可以尝试:

const open = jest.fn()
Object.defineProperty(window, 'open', open);