19

My componentDidMount() fires off a call to an async function but depending on the result of that function, it might not result in any DOM change. Is there any way I can wait for the function to complete in my tests?

Here's an example - the click button is initially disabled. If the async function returns true, the click button should be enabled:

myAsyncFunction.mockImplementation(() => true);
const {queryByText} = render(<Component />);
const button = queryByText("Click");
expect(button).toBeDisabled();
await waitFor( () => expect(button).not.toBeDisabled() );
expect(button).not.toBeDisabled();

But if it returns false the button stays disabled:

myAsyncFunction.mockImplementation(() => false);   // async returning different value
const {queryByText} = render(<Component />);
const button = queryByText("Click");
expect(button).toBeDisabled();
await waitFor( () => {} );                       //        <== **** CODE SMELL ****
expect(button).toBeDisabled();

The second test does actually work but the empty waitFor() is considsered bad practice. is there any way to avoid this?

2
  • You probably want to fire: await wait(); after rendering component: const {queryByText} = render(<Component />); await wait(); Commented Apr 2, 2020 at 14:01
  • yes, wait() is now deprecated and I beleive that waitFor(()=>{}); is the new equivalent. However I read somewhere (I think it was in the previous version of the react-testing-library docs) that an empty wait() was considered bad practice and you should wait for something concrete instead Commented Apr 4, 2020 at 10:23

1 Answer 1

36

In the docs for waitFor, it is recommended to just wait for your async function .toHaveBeenCalled like so

await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
Sign up to request clarification or add additional context in comments.

3 Comments

Aha! thanks, that text has been updated since I asked the question :-). As I understand it, this would wait for the function to be called, but not wait for the promise to be resolved. However, since it's explicit in the docs now, I guess it's OK
What is 'mockAPI' here? Ie, if one is using mswjs.io as recommended by ReactTestingLibrary, would you pass in the return value of setupServer? (I tried but got confusing results which don't indicate whether it's working or not.)
This is a direct quote from the testing-library docs, in that context mockAPI is the name they are using to refer to any asynchronous function you might need to wait for before your expectation can be asserted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.