使用浅的酶而不是安装来测试使用useEffect的组件

时间:2019-12-03 19:23:02

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



运行测试时,我得到:

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

Expected mock function to have been called, but it was not called.

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

4 个答案:

答案 0 :(得分:0)

useEffect不支持

Enzyme's shallow rendering。如on the roadmap

所述,它是ljharb(请参见专栏'v16.8 +:Hooks)的下一版固定版。

您要问的是当前设置无法实现的。但是,a lot of people are struggling with this

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

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

contact.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>
  );
}

contact.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
    );
  });
});

有用的资源

答案 1 :(得分:0)

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

TL; DR:jest.spyOn(React, 'useEffect').mockImplementation(f => f())

答案 2 :(得分:0)

我正在关注 this advice 并使用 mount() 而不是 shallow()。显然,这会导致性能下降,因此建议嘲笑儿童。

答案 3 :(得分:0)

shallow 默认情况下不会在 React 中运行效果钩子(尽管它可以在 mount 中运行),但您可以使用 jest-react-hooks-shallow 在酶中浅安装时启用 useEffect 和 useLayoutEffect 钩子。 然后测试非常简单,甚至您的测试规范也会通过。 这是一篇文章的链接,其中测试使用效果挂钩已通过酶浅安装明显解决 https://medium.com/geekculture/testing-useeffect-and-redux-hooks-using-enzyme-4539ae3cb545 所以基本上用 jest-react-hooks-shallow 来表示像

这样的组件
const ComponentWithHooks = () => {
  const [text, setText] = useState<>();
  const [buttonClicked, setButtonClicked] = useState<boolean>(false);

  useEffect(() => setText(
    `Button clicked: ${buttonClicked.toString()}`), 
    [buttonClicked]
  );

  return (
    <div>
      <div>{text}</div>
      <button onClick={() => setButtonClicked(true)}>Click me</button>
    </div>
  );
};

你会像这样编写测试

test('Renders default message and updates it on clicking a button', () => {
  const component = shallow(<App />);

  expect(component.text()).toContain('Button clicked: false');

  component.find('button').simulate('click');

  expect(component.text()).toContain('Button clicked: true');
});