Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React testing library how to use waitFor

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?

like image 679
lomine Avatar asked Jan 14 '21 19:01

lomine


People also ask

How do I use React testing library with jest?

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.

How to render an app component in react testing library?

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:

Is it possible to use wait with getby in react testing?

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.

How to find an element by specific attributes in react testing library?

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


Video Answer


1 Answers

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().

like image 173
Zsolt Meszaros Avatar answered Oct 17 '22 03:10

Zsolt Meszaros