Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use toHaveBeenCalledWith to check EventTarget

I've built a custom Input React component (think wrapper) that renders an HTML input element. When a value is entered the change is passed to the parent component like this:

const handleChange = (event: SyntheticInputEvent<EventTarget>) => {
  setCurrentValue(event.target.value);
  props.onChange(event);
};

Everything works as expected but now I want to write a test for it:

it('Should render a Text Input', () => {
  const onChange = jest.fn();

  const { queryByTestId } = renderDom(
    <Input type={InputTypesEnum.TEXT} name='car' onChange={onChange} />
  );

  const textInput = queryByTestId('text-input');
  expect(textInput).toBeTruthy();

  const event = fireEvent.change(textInput, { target: { value: 'Ford' }});
  expect(onChange).toHaveBeenCalledTimes(1);
});

This works fine too except that I want to add a final expect using toHaveBeenCalledWith. I've tried several things but can't figure out how to do it. Any ideas?

Update: I've been reading this: https://reactjs.org/docs/events.html#event-pooling. It appears that if I change handleChange like this:

const handleChange = (event: SyntheticInputEvent<EventTarget>) => {
  event.persist();
  setCurrentValue(event.target.value);
  props.onChange(event);
};

then the received object from onChange does change to include my test data. That said, I don't like the idea of altering an important feature of production code (in this case, event pooling) simply to accommodate a test.

like image 803
robertwerner_sf Avatar asked Oct 20 '25 09:10

robertwerner_sf


1 Answers

You can do something like this with toHaveBeenCalledWith

expect(onChange).toHaveBeenCalledWith(
    expect.objectContaining({
      target: expect.objectContaining({
        value: "Ford"
      })
    })
  );
like image 198
Yadab Avatar answered Oct 23 '25 00:10

Yadab



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!