15

I am using react testing library for component testing. Material UI select options are rendered in a popover. debug does not list the options. How can on click event is fired in case of select options.

Following is my select Component.

import TextField from '@material-ui/core/TextField';
import { MenuItem } from '@material-ui/core';

<TextField
  select
  id="fruit"
  inputProps={{ id: "fruit" }}
  SelectProps={{
    SelectDisplayProps: {
      'data-testid': "fruit"
    }
  }}
  fullWidth
  variant="outlined"
  {...errors}
>
  {options.map(option => (
    <MenuItem key={option[valueFieldName]} value={option[valueFieldName]}>
      {option[labelFieldName]}
    </MenuItem>
  ))}
</TextField>

What query selectors should be used for onclick event.

This is how this field is logged by debug()

    <div class="MuiFormControl-root MuiTextField-root MuiFormControl-fullWidth">
  <label
    class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined"
    data-shrink="false"
    for="fruit"
    id="fruit-label"
  >
    Action on failure
  </label>
  <div class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl">
    <div
      aria-haspopup="listbox"
      aria-labelledby="fruit-label fruit"
      class="MuiSelect-root MuiSelect-select MuiSelect-selectMenu MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
      data-testid="fruit"
      id="fruit"
      role="button"
      tabindex="0"
    >
      <span>​</span>
    </div>
    <input name="fruit" type="hidden" value="" />
    <svg
      aria-hidden="true"
      class="MuiSvgIcon-root MuiSelect-icon MuiSelect-iconOutlined"
      focusable="false"
      role="presentation"
      viewBox="0 0 24 24"
    >
      <path d="M7 10l5 5 5-5z" />
    </svg>
    <fieldset
      aria-hidden="true"
      class="PrivateNotchedOutline-root-242 MuiOutlinedInput-notchedOutline"
      style="padding-left: 8px;"
    >
      <legend
        class="PrivateNotchedOutline-legend-243"
        style="width: 0.01px;"
      >
        <span>​</span>
      </legend>
    </fieldset>
  </div>
</div>

I have another field on the same form which is rendered depending on value of this select field.

I would like to test something like this:

const selectField = screen.getByTestId('fruit');
fireEvent.change(selectField, {
    target: { value: 'APPLE' }
});
expect(selectField.value).toBe('APPLE');
expect(anotherField).toBeInTheDocument();

It fails at second expect. What is the proper way of testing such forms?

hrushilok
  • 435
  • 2
  • 5
  • 20
  • 1
    It might be late but for some devs, I was able to solve by using the `mouseDown` event see https://stackoverflow.com/questions/59567234/materialui-react-testing-library-unit-test-select-menuitem-breaks-after-upgra/59567841#59567841 – Orville Jun 04 '20 at 00:03
  • [This answer](https://stackoverflow.com/a/61491607/11768882) might help as it points out how to select the list from the document once it pops out – Arturo Mendes Jan 19 '23 at 08:49

1 Answers1

9

You should pass the data-testid prop to the inputProps like

<TextField
  select
  id="fruit"
  inputProps={{ id: "fruit", 'data-testid': "fruit" }}
  fullWidth
  variant="outlined"
  {...errors}
>

and then you can do

const fruit = getByTestId('fruit');
fireEvent.change(fruit, { target: { value: 'APPLE' } });
Gaby Garro
  • 576
  • 6
  • 12
  • Yes, this is the best approach I find also by now as Material UI is a wrapper around the base component select in this case, you have to specify the data-testId through the inputProps. – coderHook Nov 18 '20 at 21:27
  • 6
    This worked for me but it feels like it doesn't really test whether the UI works, but rather that the value can be set programmatically. – NotSimon Jan 26 '21 at 18:41
  • how can we delete `data-testid` when working with `vite`? – SalahAdDin Mar 21 '22 at 18:23