While writing tests using Jest, an asynchronous mocked Axios request was causing a setState() call after a component was mounted. This resulted in console output during the test run.
it('renders without crashing', () => {
const mockAxios = new MockAdapter(axios);
mockAxios.onGet(logsURL).reply(200, [...axios_logs_simple]);
const div = document.createElement('div');
ReactDOM.render(<Logs />, div);
ReactDOM.unmountComponentAtNode(div);
});
And in the <Logs> component:
componentDidMount() {
axios.get(apiURL).then(response => {
this.setState({data: response.data});
});
}
I found a blog post showing a solution, but I don't understand how it does anything useful:
it('renders without crashing', async () => { //<-- async added here
const mockAxios = new MockAdapter(axios);
mockAxios.onGet(logsURL).reply(200, [...axios_logs_simple]);
const div = document.createElement('div');
ReactDOM.render(<Logs />, div);
await flushPromises(); //<-- and this line here.
ReactDOM.unmountComponentAtNode(div);
});
const flushPromises = () => new Promise(resolve => setImmediate(resolve));
As I understand it, it creates a new promise that resolves immediately. How can that guarantee other asynchronous code will resolve?
Now, it solved the issue. There are no more console messages during the test run. The test still passes (it's not a very good one). But this just seems like I just landed on the other side of a race condition, rather than preventing the race condition in the first place.