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 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…