首页 > 解决方案 > 用 Jest 只模拟一个“window”属性

问题描述

我有一个调用window.location.href.

作为我 Jest 测试的一部分,我模拟window.location.href如下的值:

const mockWindow = { location: { href: 'https://stackoverflow.com/questions' } };
jest.spyOn(window, 'window', 'get').mockImplementation(() => mockWindow);

const wrapper = mount(<MyComponent />);

但是,当我运行它时,我收到以下错误:

TypeError: Right-hand side of 'instanceof' is not an object

    > |   const wrapper = mount(<MyComponent />);
      |                   ^

这告诉我在渲染/安装组件时存在内部 React 问题。这个问题是由我模拟window对象引起的。当我取消注释该行并重新运行它时,它不会引发此错误。

猜测React 在内部会进行其他调用,window.*并且因为我模拟了整个对象,所以 React 进行的那些调用返回undefined并且组件不会呈现。

我如何只模拟一个属性window而保持其他属性不变?

或者,还有其他原因会出错吗?还是有其他巧妙的方法来解决这个问题?

标签: javascriptjestjsmockingwindowenzyme

解决方案


而不是 jest.spyOn(window, 'window'...) 尝试使用 (global, 'window'...) ,如下所示:

const originalWindow = { ...window };
const windowSpy = jest.spyOn(global, "window", "get");
windowSpy.mockImplementation(() => ({
  ...originalWindow,
  location: {
    ...originalWindow.location,
    href: "http://my.test/page",
    replace: mockedReplace,
  },
}));

在记住清理它之后:

windowSpy.mockRestore();

您可以按照此示例更好地检查


推荐阅读