Reputation: 11890
I have a parent component that does the following:
input
fieldsPOST
request with the <form>
data is made to the server using axios
Error
response is returned, an error message is rendered inside a <span>
element on the formI'm writing the following test for this scenario
import axios from 'axios';
import { expect } from 'chai';
import { mount } from 'enzyme';
jest.mock('axios');
it('displays an error when the submit fails', async () => {
const wrapper = mount(<MyComponent />);
// Fill in form input fields with text (not shown)
// ....
// ....
// Mock the axios `POST` call to return an error
const errorResponse = { response: { data: { errors: [{ title: 'Some error' }] } } }
axios.post.mockImplementationOnce(() => Promise.reject(errorResponse));
// Click Submit and wait on the axios Promise to complete
const submit = wrapper.find('.my-component__submit-btn').first();
await submit.simulate('click');
// Check if error was rendered on the form
wrapper.update();
const error = wrapper.find('.my-component__submit-error').first();
expect(error).to.have.text('Some error'); // This fails!
});
The last expect()
fails - no error is set but I expect one to exist.
However if I add an artificial delay via setTimeout
, it passes. So clearly it's an issue where the React component tree does not update before the expect()
checks it.
Is there a clean way to "wait" on the React tree to re-render without using setTimeout
?
I thought wrapper.update()
would do this, but it doesn't seem to.
Thanks!
Upvotes: 3
Views: 5648
Reputation: 551
There is a way to wait for all promises to resolve. Define:
const waitForPromises = () => new Promise(setImmediate);
Then, after the component has rendered, wait:
await waitForPromises()
This, though working in most cases, will still not work if the component is internally updating its state, without triggering these state updates from its properties.
I believe when the latter is the case, this is just an untestable pattern, and requires change in the application design approach, rather than the testing methods.
Upvotes: 1