How to test a <select> element with React Testing Library

I recently needed to add tests for a <select> element I was developing, and I couldn’t find a lot of resources on how to do this with React Testing Library, so I’ll share the approach I went with.

The <select> element

First of …


This content originally appeared on DEV Community and was authored by ReturnOfTheMac 🚀

I recently needed to add tests for a <select> element I was developing, and I couldn't find a lot of resources on how to do this with React Testing Library, so I'll share the approach I went with.

The <select> element

First of all, let's create a <select> element with some options. Here I have an array with 3 countries:

const countries = [ 
  { name: "Austria", isoCode: "AT" },
  { name: "United States", isoCode: "US" }, 
  { name: "Ireland", isoCode: "IE" }, 
]

Here's the <select> element itself, it has:

  1. A default placeholder <option> asking the user to "Select a country".
  2. A .map method so we can iterate over the countries array and add an <option> element for each one.
<select>
  <option>Select a country</option>
  {countries.map(country => (
    <option key={country.isoCode} value={country.isoCode}>
      {country.name}
    </option>
  ))}
</select>

Tests

Now that we have a basic <select> element which displays some countries, let's go ahead and write some tests! Yay...my favourite part 😀

The beauty of React Testing Library is that it makes you focus more on writing tests the way an actual user would interact with your application, so that's the approach I've taken with the tests below. Of course you may have your own unique scenarios, if you do, just think "How would a real user interact with my select element?".

Default selection

it('should correctly set default option', () => {
  render(<App />)
  expect(screen.getByRole('option', { name: 'Select a country' }).selected).toBe(true)
})

Correct number of options

it('should display the correct number of options', () => {
  render(<App />)
  expect(screen.getAllByRole('option').length).toBe(4)
})

Change selected option

it('should allow user to change country', () => {
  render(<App />)
  userEvent.selectOptions(
    // Find the select element, like a real user would.
    screen.getByRole('combobox'),
    // Find and select the Ireland option, like a real user would.
    screen.getByRole('option', { name: 'Ireland' }),
  )
  expect(screen.getByRole('option', { name: 'Ireland' }).selected).toBe(true)
})

Gotchas

Initially when I started to look into writing tests for these scenarios I went with the following approach:

it('should allow user to change country', () => {
  render(<App />)
  userEvent.selectOptions(
    screen.getByRole('combobox'),
    screen.getByRole('option', { name: 'Ireland' } ),
  )
  expect(screen.getByRole('option', { name: 'Ireland' })).toBeInTheDocument();
})

Notice the difference? I was only checking that the "Ireland" <option> existed instead of checking if it was actually selected. Yet my test was still passing 🤔

expect(screen.getByRole('option', { name: 'Ireland' })).toBeInTheDocument();

Let's take a look at why this happened. When the component is loaded, the following is rendered:

<select>
  <option value="">Select a country</option>
  <option value="US">United States</option>
  <option value="IE">Ireland</option>
  <option value="AT">Austria</option>
</select>

So from JSDOM's point of view, the "Ireland" <option> always exists within the document, causing my test to pass!

Whereas the correct approach is to use .selected:

expect(screen.getByRole('option', { name: 'Ireland' }).selected).toBe(true);

Gotchas like this can be just as dangerous as not writing the test in the first place as it gives you false confidence about your tests. This is why I always recommend intentionally causing your tests to fail, like this:

expect(screen.getByRole('option', { name: 'Austria' }).selected).toBe(true);
❌ Test failed: should allow user to change country
Expected: true
Received: false

This way you can be confident that it only passes for the intended scenario 🥳

Full code example

Here's a codesandox which includes the basic examples shown above.

Final thoughts

So there it is, you should now be able to write some basic tests for your <select> elements using React Testing Library. Of course, I'm not an expert on this topic, I'm simply sharing what I learned in the hope that I can pass on some knowledge.

If you found this article useful, please give it a like and feel free to leave any feedback in the comments 🙏


This content originally appeared on DEV Community and was authored by ReturnOfTheMac 🚀


Print Share Comment Cite Upload Translate Updates
APA

ReturnOfTheMac 🚀 | Sciencx (2021-10-10T15:52:27+00:00) How to test a <select> element with React Testing Library. Retrieved from https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/

MLA
" » How to test a <select> element with React Testing Library." ReturnOfTheMac 🚀 | Sciencx - Sunday October 10, 2021, https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/
HARVARD
ReturnOfTheMac 🚀 | Sciencx Sunday October 10, 2021 » How to test a <select> element with React Testing Library., viewed ,<https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/>
VANCOUVER
ReturnOfTheMac 🚀 | Sciencx - » How to test a <select> element with React Testing Library. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/
CHICAGO
" » How to test a <select> element with React Testing Library." ReturnOfTheMac 🚀 | Sciencx - Accessed . https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/
IEEE
" » How to test a <select> element with React Testing Library." ReturnOfTheMac 🚀 | Sciencx [Online]. Available: https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/. [Accessed: ]
rf:citation
» How to test a <select> element with React Testing Library | ReturnOfTheMac 🚀 | Sciencx | https://www.scien.cx/2021/10/10/how-to-test-a-select-element-with-react-testing-library/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.