react-testing-library for material ui Text input

Viewed 11630

My Text Input is:

<TextField
  className={classes.textField}
  data-testid={name}
  variant="outlined"
  error={false}
  required
  onChange={(element) => {
    if (onTextChange) {
      onTextChange(name, element.target.value);
    }
  }}
  disabled={!editEnable}
  name={name}
  label={label}
  defaultValue={values}
  fullWidth
/>;

and UI:

Screenshot of HTML with an input field highlighted

How to change the value of this text element in the React testing library?

3 Answers

In my case it works like this

it('should render input ', () => {
    const field  = screen.getByTestId('search-text-field').querySelector('input')
    expect(field ).toBeInTheDocument()

    fireEvent.change(field , {target: { value: 'google it'}});
    expect(field.value).toBe('google it');
});

I don't think getting the input by the display value is a good idea as if that changes the whole test will fail. Instead you should get the label of the input field.

screen.getByLabelText(/^label/i)

Update

Just realised that my way only works if you include an id to the TextField and the ID must match the name. This does seem to be the preferred way to get the input via Material UI as you don't need to include a test-id or by the value.

<TextField
    name={name}
    id={name}
    label={label}
    {...otherProps}
/>

I often struggle to get Material UI and react-testing-library working. But if you know your "recipes" it's always the same.

Here is an example of an TextField

import * as React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { TextField } from '@material-ui/core';

const inputMock = jest.fn();

const Test = () => (
  <TextField
    data-testid={name}
    variant="outlined"
    error={false}
    required
    onChange={inputMock}
    name={name}
    label={'label'}
    defaultValue={'4711'}
    placeholder={'Enter Number'}
    fullWidth
  />
);

test('Input', () => {
  const container = render(<Test />);

  const input = container.getByDisplayValue('4711') as HTMLInputElement;

  fireEvent.change(input, { target: { value: '42' } });
  expect(input.value).toBe('42');
  expect(inputMock.mock.calls).toHaveLength(1);
});

Here are some advises which selectors to use. So you can try a "better" one. https://testing-library.com/docs/guide-which-query

Cheers Thomas

Related