How do I trigger the change event on a react-select component with react-testing-library?

My team has a test utility in our project that lets us select an item easily after spending too much time trying to figure out how to do this properly. Sharing it here to hopefully help others.

This doesn't rely on any React Select internals or mocking but does require you to have set up a <label> which has a for linking to the React Select input. It uses the label to select a given choice value just like a user would on the real page.

const KEY_DOWN = 40

// Select an item from a React Select dropdown given a label and
// choice label you wish to pick.
export async function selectItem(
  container: HTMLElement,
  label: string,
  choice: string
): Promise<void> {
  // Focus and enable the dropdown of options.
  fireEvent.focus(getByLabelText(container, label))
  fireEvent.keyDown(getByLabelText(container, label), {
    keyCode: KEY_DOWN,
  })

  // Wait for the dropdown of options to be drawn.
  await findByText(container, choice)

  // Select the item we care about.
  fireEvent.click(getByText(container, choice))

  // Wait for your choice to be set as the input value.
  await findByDisplayValue(container, choice)
}

It can be used like this:

it('selects an item', async () => {
  const { container } = render(<MyComponent/>)

  await selectItem(container, 'My label', 'value')
})

You can try the following to get it working:

  1. Fire focus event on the ReactSelect component .react-select input element.
  2. Fire a mouseDown event on the .react-select__control element
  3. Fire a click on the option element that you want to select

You can add a className and classNamePrefix props with the value of "react-select" in order to specifically select the component you are trying to test.

PS: In case you are still stuck I'd encourage you to take a look at this conversation from where the above answer is borrowed - https://spectrum.chat/react-testing-library/general/testing-react-select~5857bb70-b3b9-41a7-9991-83f782377581