I'm following a tutorial on React testing. The tutorial has a simple component like this, to show how to test asynchronous actions:
import React from 'react'
const TestAsync = () => {
const [counter, setCounter] = React.useState(0)
const delayCount = () => (
setTimeout(() => {
setCounter(counter + 1)
}, 500)
)
return (
<>
<h1 data-testid="counter">{ counter }</h1>
<button data-testid="button-up" onClick={delayCount}> Up</button>
<button data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button>
</>
)
}
export default TestAsync
And the test file is like this:
import React from 'react';
import { render, cleanup, fireEvent, waitForElement } from '@testing-library/react';
import TestAsync from './TestAsync'
afterEach(cleanup);
it('increments counter after 0.5s', async () => {
const { getByTestId, getByText } = render(<TestAsync />);
fireEvent.click(getByTestId('button-up'))
const counter = await waitForElement(() => getByText('1'))
expect(counter).toHaveTextContent('1')
});
The terminal says waitForElement
has been deprecated and to use waitFor
instead.
How can I use waitFor
in this test file?
If you want to use React Testing Library outside of a CRA application, then you need to install both React Testing Library and Jest manually with NPM: You need to install Jest because React Testing Library only provides methods to help you write the test scripts. So you still need a JavaScript test framework to run the test code.
The test code above used React Testing Library's render method to virtually render the App component imported from App.js file and append it to the document.body node. You can access the rendered HTML through the screen object. To see the result of the render () call, you can use the screen.debug () method:
I found the answer here: React Testing Library - using 'await wait ()' after fireEvent TLDR: "You can not use wait with getBy*. getBy is not async and will not wait." Better is to use findBy*. This is the async version of getBy.
Most of your React test cases should use methods for finding elements. React Testing Library provides you with several methods to find an element by specific attributes in addition to the getByText () method above: getByText (): find the element by its textContent value getByRole (): by its role attribute value
If you're waiting for appearance, you can use it like this:
it('increments counter after 0.5s', async() => {
const { getByTestId, getByText } = render(<TestAsync />);
fireEvent.click(getByTestId('button-up'));
await waitFor(() => {
expect(getByText('1')).toBeInTheDocument();
});
});
Checking .toHaveTextContent('1')
is a bit "weird" when you use getByText('1')
to grab that element, so I replaced it with .toBeInTheDocument()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With