简体   繁体   中英

Material-UI TextField onChange doesn't invoke function in a test

I'm learning both Jest and React and experimenting with Material-UI. I wrote this simple test just to check how things work:

import React from 'react';
import { render, fireEvent, configure} from '@testing-library/react';

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

configure({ testIdAddribute: 'id' });

describe('Testing events', () => {

  test('onChange', () => {
    const onChangeMock = jest.fn();
    
    const { getByTestId } = render(
      <TextField id="test" onChange={onChangeMock} type="text" />
    );
    
    fireEvent.change(getByTestId('test', { target: { value: 'foo' } }));
    expect(onChangeMock.mock.calls.length).toBe(1);
  });
});

But this test fails:

expect(received).toBe(expected) // Object.is equality

    Expected: 1
    Received: 0

What am I not understanding here?

getByTestId() will look for data-testid attribute, not id . Try changing your code from

<TextField id="test" onChange={onChangeMock} />

To

<TextField inputProps={{ 'data-testid': 'test' }} onChange={onChangeMock} />

Now in your code

fireEvent.change(getByTestId('test', { target: { value: 'foo' }})); expect(onChangeMock.mock.calls.length).toBe(1);

When simulating key presses from the user, you should use @testing-library/user-event and call user.type() instead of firing the the onChange event yourself manually.

You can also use .toHaveBeenCalledTimes(number) matcher to assert how many times the function had been invoked.

And finally, you should use getByRole() instead of getByTestId() because the user will see the TextField ( getByRole('textbox') ) instead of data-testid attribute of the element which you can only see when inspecting the elements.

See the Which query should I use? to know more about the philosophy of RTL.

Put it together, you will have something like this:

import { screen } from '@testing-library/dom'
import user from '@testing-library/user-event'

...

const onChangeMock = jest.fn();
    
render(<TextField onChange={onChangeMock} />);

const input = screen.getByRole('textbox')

user.type(input, 'foo')
expect(onChangeMock).toHaveBeenCalledTimes(3);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM