1

I have a Material UI select component id like to automate tests with jest. Is it possible to select an option within a list selector Material UI component and have the option populate its value confirmably in jest? I am unable to find any reliable method or information on how to do this.

polar
  • 524
  • 5
  • 24
  • 2
    This question looks like a duplicate https://stackoverflow.com/questions/52930419/how-to-simulate-selecting-from-dropdown-in-jest-enzyme-testing, please verify the given solution. This should work if not let me know. – Dibyanshu Banerjee Feb 08 '22 at 16:31
  • 1
    @polar please add the snippet about what you have tried so far so that we can help you. Also add relevant details to your question. – Subrato Pattanaik Feb 09 '22 at 08:06
  • Does this answer your question? [React testing library on change for Material UI Select component](https://stackoverflow.com/questions/55184037/react-testing-library-on-change-for-material-ui-select-component) – DarkTrick Nov 10 '22 at 10:46

3 Answers3

0

In MUI library all input components have a property called inputProps. This property is forwarded to the html <input /> at the end of the tree. So you can pass a property that identifies the input so you can use it to find and interact with it.

0

MUI isn't that different.

Have you tried something like this?

import {render, screen, fireEvent} from '@testing-library/react'

test('should pick select option', () => {
  render(<MyCustomMUIComponent />)
  const select = screen.getByLabelText('My Select');
  fireEvent.click(select);
  const option = screen.getByText('First Option');
  fireEvent.click(option);

  // the effect you want to test for
})
acolchagoff
  • 1,926
  • 3
  • 18
  • 30
  • Didn't work for me when using `` (and replacing `getByLabelText` with `getByTestId`) – DarkTrick Nov 10 '22 at 10:41
0

This way of doing things worked for me:

test('MUI Select test', async () => {
  const spyOnSelectChange = jest.fn();

  render(<Select defaultValue='option_1_key'
          onChange={spyOnSelectChange}>
            <MenuItem value='option_1_key'>option_1_value</MenuItem>
            <MenuItem value='option_2_key'>option_2_value</MenuItem>
        </Select>)

  // Check current state
  {
    expect(screen.queryByText('option_1_value')).toBeTruthy();
    expect(screen.queryByText('option_2_value')).not.toBeTruthy();
  }

  // Change Selection
  {
    // Note: you need to use the *keys*, not the actual text shown
    const select = screen.getByDisplayValue("option_1_key")
    // no act/await needed (why?)
    fireEvent.change(select, { target: { value: 'option_2_key' } })
  }
  

  // check if onChange was called
  expect(spyOnSelectChange.mock.calls.length).toBe(1);

  // Check new state
  {
    expect(screen.queryByText('option_1_value')).not.toBeTruthy();
    expect(screen.queryByText('option_2_value')).toBeTruthy();
  }
})

Note:

  • const select = screen.getByTestId("your_test_id"); wouldn't work.

  • Another answer stated you'd need await waitFor(() => {expect(spyOnSelectChange.mock.calls.length).toBe(1);}). I didn't.

DarkTrick
  • 2,447
  • 1
  • 21
  • 39