mycodegoesKABOOM
mycodegoesKABOOM

Reputation: 297

React testing library - waiting for state update before testing component

I am testing a combobox on first render the initial value of the combobox is undefined. Then using query parameters and a useEffect the the component find the relevant option and sets the value state to it.


const Component = () => {

[value, setValue] = useState(undefined);

useEffect(() => {

setValue("hello")

}, [])


return(
<Combobox value={value}/>
)

}

it("should render with value as hello", () => {

const {getByText} = render(<Component/>)

const text = getByText("hello")

})

That test suite throws this error:

TestingLibraryElementError: Unable to find an element with the text: Photobug. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

When testing in react testing library. I cannot retrieve the expected text value this is because it shows what has been rendered on first render. Which would have been nothing because value is undefined.

I have tried a combination of async methods. Aync await pattern, await waitFor(() => ), findByText etc all to no avail.

Upvotes: 16

Views: 36489

Answers (1)

Ankit Saxena
Ankit Saxena

Reputation: 1197

Looks like in your test you need to wait till your component is fully rendered. You can use waitFor method provided by react testing library.

I tried to reproduce your issue with an input box.

Component:

import { useState, useEffect } from "react";

export const Component = () => {

  const[value, setValue] = useState('');
  
  useEffect(() => {
  
  setValue("hello")
  
  }, [])
  
  
  return(
  <input value={value}/>
  )
  
  }

Test case :

it("should render with value as hello", async () => {
    const {getByRole} = render(<Component/>)
    await waitFor(() => expect(getByRole('textbox')).toHaveValue('hello'))
    })

In your case, you have to give role as combobox.

    await waitFor(() => expect(getByRole('combobox')).toHaveValue('hello'))

Upvotes: 16

Related Questions