使用 Enzyme 浅而不是挂载测试使用 useEffect 的组件

Ado*_*lfo 13 reactjs enzyme

// MyComponent.jsx
const MyComponent = (props) => {
  const { fetchSomeData } = props;

  useEffect(()=> {
    fetchSomeData();
  }, []);

  return (
    // Some other components here
  )
};

// MyComponent.react.test.jsx
...
describe('MyComponent', () => {
  test('useEffect', () => {
    const props = {
      fetchSomeData: jest.fn(),
    };

    const wrapper = shallow(<MyComponent {...props} />);

    // THIS DOES NOT WORK, HOW CAN I FIX IT?
    expect(props.fetchSomeData).toHaveBeenCalled();
  });
});



Run Code Online (Sandbox Code Playgroud)

运行测试时,我得到:

expect(jest.fn()).toHaveBeenCalled()

Expected mock function to have been called, but it was not called.
Run Code Online (Sandbox Code Playgroud)

期望失败,因为shallow没有调用 useEffect。由于其他问题,我无法使用 mount,需要找到一种使用shallow.

nde*_*ker 9

酶的浅渲染不支持useEffect。正如ljharb所提到的,它在路线图上(参见“v16.8+:Hooks”列)将在下一版本的 Enzyme 中修复

当前设置无法满足您的要求。然而,很多人都在为此苦苦挣扎

我已经通过以下方式解决/解决了这个问题:

  • 不再使用 Enzyme 的浅渲染
  • 使用React 测试库而不是 Enzyme
  • 通过 Jest 模拟模块

这是基于React 文档中的Mock Modules 的关于如何模拟模块的摘要。

联系人.js

import React from "react";
import Map from "./map";

function Contact(props) {
  return (
    <div>
      <p>
        Contact us via foo@bar.com
      </p>
      <Map center={props.center} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

联系.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";

import Contact from "./contact";
import MockedMap from "./map";

jest.mock("./map", () => {
  return function DummyMap(props) {
    return (
      <p>A dummy map.</p>
    );
  };
});

it("should render contact information", () => {
  const center = { lat: 0, long: 0 };
  act(() => {
    render(
      <Contact
        name="Joni Baez"
        email="test@example.com"
        site="http://test.com"
        center={center}
      />,
      container
    );
  });
});
Run Code Online (Sandbox Code Playgroud)

有用的资源:

  • 我不明白这与 OP 的 useEffect 问题有什么关系 (2认同)

Len*_*y T 6

这是我在 CarbonFive 的一位同事的解决方案:https ://blog.carbonfive.com/2019/08/05/shallow-testing-hooks-with-enzyme/

特尔;博士: jest.spyOn(React, 'useEffect').mockImplementation(f => f())

  • 这很有用,但如果您在一个文件中使用多个 useEffect,那么组件中 useEffect 的顺序可能会影响测试的结果。 (3认同)
  • @PositiveGuy 那么模拟使用效果或模拟用户点击和状态如何更改的最佳方法是什么? (3认同)