This solution didn't work for me, what did work, was userEvent.
https://testing-library.com/docs/ecosystem-user-event/
import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from './App';
test('Simulates selection', () => {
const { getByTestId } = render(<App />);
// where <value> is the option value without angle brackets!
userEvent.selectOptions(getByTestId('select'), '<value>');
expect((getByTestId('<value>') as HTMLOptionElement).selected).toBeTruthy();
expect((getByTestId('<another value>') as HTMLOptionElement).selected).toBeFalsy();
//...
})
You can also forgo having to add a data-testid
to the select element if you have a label (which you should!), and simply use getByLabelText('Select')
Further still, you can get rid of the additional data-testid
on each option element, if you use getByText
.
<label for="selectId">
Select
</label>
<select
onChange={handleChoice}
id="selectId"
>
<option value="default">Make your choice</option>
{attributes.map(item => {
return (
<option key={item.key} value={item.key}>
{item.label}
</option>
);
})}
</select>
Then:
import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import App from './App';
test('Simulates selection', () => {
const { getByLabelText, getByText } = render(<App />);
// where <value> is the option value without angle brackets!
userEvent.selectOptions(getByLabelText('<your select label text>'), '<value>');
expect((getByText('<your selected option text>') as HTMLOptionElement).selected).toBeTruthy();
expect((getByText('<another option text>') as HTMLOptionElement).selected).toBeFalsy();
//...
})
This seems a more optimal way to do this type of test.
fireEvent.change(getByTestId("select"), { target: { value: '<item label>' } });
– Buster