首页 > 解决方案 > 测试使用 Hooks 获取数据的 React 组件

问题描述

我的 React 应用程序有一个组件,它从远程服务器获取要显示的数据。在前钩子时代,componentDidMount()是去的地方。但现在我想为此使用钩子。

const App = () => {
  const [ state, setState ] = useState(0);
  useEffect(() => {
    fetchData().then(setState);
  });
  return (
    <div>... data display ...</div>
  );
};

我使用 Jest 和 Enzyme 的测试如下所示:

import React from 'react';
import { mount } from 'enzyme';
import App from './App';
import { act } from 'react-test-renderer';

jest.mock('./api');

import { fetchData } from './api';

describe('<App />', () => {
  it('renders without crashing', (done) => {
    fetchData.mockImplementation(() => {
      return Promise.resolve(42);
    });
    act(() => mount(<App />));
    setTimeout(() => {
      // expectations here
      done();
    }, 500);
  });  
});

测试成功,但它记录了一些警告:

console.error node_modules/react-dom/cjs/react-dom.development.js:506
    Warning: An update to App inside a test was not wrapped in act(...).

    When testing, code that causes React state updates should be wrapped into act(...):

    act(() => {
    /* fire events that update state */
    });
    /* assert on the output */

    This ensures that you're testing the behavior the user would see in the browser. Learn more at (redacted)
        in App (created by WrapperComponent)
        in WrapperComponent

App 组件的唯一更新发生在 Promise 回调中。我怎样才能确保这发生块内act?文档明确建议在块之外进行断言。act此外,将它们放入内部不会改变警告。

标签: reactjsjestjsenzymereact-hooksreact-test-renderer

解决方案


该问题是由 Component 内部的许多更新引起的。

我遇到了同样的问题,这将解决问题。

await act( async () => mount(<App />));

推荐阅读