My 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
. Кроме того, размещение их внутри не меняет предупреждение.