9

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.

mycodegoesKABOOM
  • 187
  • 1
  • 2
  • 9
  • 1. If the initial value of state is hello, just pass it as the initial value, the effect is useless. 2. What is Combobox? – Adam Jenkins Feb 27 '22 at 16:10
  • The initial value isn’t hello. This was just to demonstrate the issue. I still need to set the state in the effect. I want to get around the issue with the testing library if you can advise. Thanks. – mycodegoesKABOOM Feb 27 '22 at 18:31
  • Can't reproduce your issue. Please provide a minimal, complete, reproducible example – Lin Du Feb 28 '22 at 03:05

1 Answers1

10

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'))

Ankit Saxena
  • 1,067
  • 1
  • 4
  • 16