如何使用 Jest 和 Enzyme 对 useEffect cleanUp 返回函数进行单元测试

use*_*234 14 reactjs jestjs enzyme

我尝试了很多场景,但都没有奏效,我面临 useEffect Cleanup 返回方法的问题。寻找一些解决方案来覆盖用例。由于声誉较低,无法附上屏幕截图。

我做了一些研究并遵循了提供的解决方案,例如创建 spyOn、mount、unMount 场景。但没有一个奏效。

useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    window.addEventListener('resize', handleResize);
    return () => {
       window.removeEventListener('scroll', handleScroll);
       window.removeEventListener('resize', handleResize);
    };
}, []);

Run Code Online (Sandbox Code Playgroud)

期望对 useEffect 函数内的 return 语句进行测试覆盖。

请原谅错别字 - 从手机发布。

Alb*_*ing 11

我建议你检查react-testing-library。该库提供了一种unmount方法,该render方法从其方法中返回。调用 后unmount(),您可以检查侦听器是否已被删除。总的来说,我非常推荐 react-testing-library。我们将它与 jest 结合用于我们所有的前端测试,它就像一个魅力。

unmount方法的示例用法:

import { render } from "@testing-library/react";

it("Should do what I want", () => {
  const { unmount } = render(
    <MyComponent value="test" } />
  );

  unmount();

  // ... expects
});
Run Code Online (Sandbox Code Playgroud)

  • 你验证这是否有效吗?对我来说,卸载不会调用 useEffect 中的任何清理函数 (2认同)

小智 9

为了运行您在 useEffect 钩子中指定的清理函数,您可以缓存对它的引用,然后在测试中稍后调用该引用:

let cleanupFunc;

jest.spyOn(React, "useEffect").mockImplementationOnce(func => {
    cleanupFunc = func();
});

cleanupFunc();
Run Code Online (Sandbox Code Playgroud)

  • 此解决方法不允许为“useEffect”指定依赖项,并且如果直接导入“useEffect”而不是用作“React.useEffect”,它也将不起作用。 (3认同)

小智 6

这是解决我的问题的完整答案:

it('Should run useEffect cleanUp return function', () => {
  const remover = jest
    .spyOn(global, 'removeEventListener')
    .mockImplementation(() => {});
  act(() => {
    component = mount( < MyComponent value = "Test" / > );
  });
  component.unmount();

  expect(remover).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)


Tha*_*wig 5

对于那些像我一样无法使已接受的答案发挥作用的人:

jest.spyOn(React, "useEffect").mockImplementationOnce(cb => cb()());

将第二个添加()到回调中可以执行清理工作。