Reactjs jest/酶测试事件侦听器已删除

Reactjs jest/酶测试事件侦听器已删除,reactjs,jestjs,enzyme,create-react-app,Reactjs,Jestjs,Enzyme,Create React App,学习jest和Ezyme测试react应用程序,使用create react应用程序引导 模拟add/removeEventListener在shallow之后使用unmount崩溃,并在mount之后使用unmount发出警告,请参见下文。有人知道我做错了什么吗 我的测试: it('should add and remove resize event handler', () => { const adder = jest .spyOn(global, 'addEventLi

学习jest和Ezyme测试react应用程序,使用create react应用程序引导

模拟add/removeEventListener在
shallow
之后使用
unmount
崩溃,并在
mount
之后使用
unmount
发出警告,请参见下文。有人知道我做错了什么吗

我的测试:

it('should add and remove resize event handler', () => {
  const adder = jest
    .spyOn(global, 'addEventListener')
    .mockImplementation(() => {});
  const remover = jest
    .spyOn(global, 'removeEventListener')
    .mockImplementation(() => {});
  const wrapper = shallow(<App />);
  // this seems to work
  expect(adder).toHaveBeenCalled();
  // causing issues
  wrapper.unmount();
  expect(remover).toHaveBeenCalled();
});
shall
之后使用
unmount

/home/nik/projects/learn/jest/node_modules/react-scripts/scripts/test.js:20
  throw err;
  ^

Invariant Violation: ReactShallowRenderer render(): Invalid component element.
    at invariant (/home/nik/projects/learn/jest/node_modules/fbjs/lib/invariant.js:42:15)
    at ReactShallowRenderer.render (/home/nik/projects/learn/jest/node_modules/enzyme-adapter-react-16/node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:104:38)
    at Updater.enqueueSetState (/home/nik/projects/learn/jest/node_modules/enzyme-adapter-react-16/node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:329:20)
    at App.Object.<anonymous>.Component.setState (/home/nik/projects/learn/jest/node_modules/react/cjs/react.development.js:237:16)
    at loadData.then.results (/home/nik/projects/learn/jest/src/App.js:15:12)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
error An unexpected error occurred: "Command failed.
Exit code: 1
Command: sh
Arguments: -c react-scripts test --env=jsdom
Directory: /home/nik/projects/learn/jest
Output:
".
info If you think this is a bug, please open a bug report with the information provided in "/home/nik/projects/learn/jest/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
/home/nik/projects/learn/jest/node_modules/react scripts/scripts/test.js:20
犯错误;
^
不变冲突:ReactShallerRender():无效的组件元素。
at invariant(/home/nik/projects/learn/jest/node_modules/fbjs/lib/invariant.js:42:15)
在reactshallwrender.render(/home/nik/projects/learn/jest/node_modules/enzyme-adapter-react-16/node_modules/react test renderer/cjs/react test renderer shall.development.js:104:38)
在Updater.enqueueSetState(/home/nik/projects/learn/jest/node_modules/enzyme-adapter-react-16/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:329:20)
在App.Object..Component.setState(/home/nik/projects/learn/jest/node_modules/react/cjs/react.development.js:237:16)
在loadData.then.results(/home/nik/projects/learn/jest/src/App.js:15:12)
在
在进程中。_tick回调(内部/process/next_tick.js:188:7)
错误发生意外错误:“命令失败。
退出代码:1
命令:sh
参数:-c react脚本测试--env=jsdom
目录:/home/nik/projects/learn/jest
输出:
".
信息如果您认为这是一个bug,请打开一个bug报告,其中包含“/home/nik/projects/learn/jest/warn error.log”中提供的信息。
信息访问https://yarnpkg.com/en/docs/cli/run 有关此命令的文档。

要解决第一个问题,必须采取步骤避免在卸载组件后调用
setState

更简单的方法是维护
\u isMounted
标志,您将在调用setState之前检查该标志:

componentDidMount() {
  this._isMounted = true;

  this.loadData().then(results => {
    if (!this._isMounted) {
      return;
    }

    const [topics, subTopics, ...rest] = results;

    this.setState({ topics, subTopics });
  });

  window.addEventListener('resize', this.someHandler);
}

componentWillUnmount() {
  this._isMounted = false;

  window.removeEventListener('resize', this.someHandler);
}

您可以阅读有关此问题的更多信息,并在React博客中找到另一个解决方案:

我将卸载包装在promise中

  return Promise.resolve().then(() => {
    wrapper.unmount();
    expect(remover).toHaveBeenCalled();
  });
在错误“loadData”中也漏掉了一条线索,这不是在嘲笑:

  jest.spyOn(App.prototype, 'loadData')
    .mockImplementation(() => {
      return new Promise(resolve => resolve([topics, subTopics]))
    });

你能发布
应用程序的源代码吗?
?这里是:我不喜欢你的解决方案,对不起。。。但它让我思考为什么我在
…Unmount
中调用setState。我想可能我调用
unmount
太快了,所以将它包装在一个return
Promise.resolve().then()
中,它似乎起了作用,尽管我不敢相信我还没有尝试过。
  jest.spyOn(App.prototype, 'loadData')
    .mockImplementation(() => {
      return new Promise(resolve => resolve([topics, subTopics]))
    });