Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
821 views
in Technique[技术] by (71.8m points)

reactjs - Testing React components that fetches data using Hooks

My React-application has a component that fetches data to display from a remote server. In the pre-hooks era, componentDidMount() was the place to go. But now I wanted to use hooks for this.

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

And my test using Jest and Enzyme looks like this:

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

The test succeeds, but it logs a few warnings:

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

The only update to the App component happens from the Promise callback. How can I ensure this happens within the act block? The docs clearly suggest to have assertions happen outside the act block. Besides, putting them inside doesn't change the warning.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

That issue is caused by many updates inside Component.

I got the same issue, this would solve the issue.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...