0
votes

I have a simple Input component which I want to test with jest, enzyme.

import TextField from '@material-ui/core/TextField';
import React from 'react';

const TextComponent = (props) => {
  const handleInputChange = (name) => ({ target }) => {
    props.handleChange({ [name]: target.value }, target.value);
  };
  return (
    <TextField onChange={handleInputChange(props.name)} {...props} className="textComponent" />
  );
};

export default TextComponent;

My test case look like this

import React from 'react';
import { mount } from 'enzyme';
import { TextComponent } from '../../../tests';

test('<TextComponent> with label, name', () => {
  const onChangeMock = jest.fn();
  const handleChangeMock = jest.fn();
  const input = mount(
    <TextComponent
      label="Test"
      onChange={onChangeMock}
      value="test value"
      variant="outlined"
      name="testname"
      handleChange={handleChangeMock}
    />
  );
  expect(input.props().label).toEqual('Test');
  expect(input.props().name).toEqual('testname');
  expect(input.props().variant).toEqual('outlined');
  input.find('input').simulate('change');
  expect(handleChangeMock).toBeCalledWith({testname: 'test value'}, 'test value');
});

While running the test case I am getting an error saying

Warning: React does not recognize the `handleChange` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it
 as lowercase `handlechange` instead. If you accidentally passed it from a parent component, remove it from the DOM element.

How can I test if my handleChangeMock function is being invoked with the correct data?

1

1 Answers

0
votes

In your tests, these props are passed to TextComponent

//...
      label="Test"
      onChange={onChangeMock}
      value="test value"
      variant="outlined"
      name="testname"
      handleChange={handleChangeMock}
//...

However in TextComponent implementation all these props are forwarded in MUITextField after decorating handleChange prop.

<TextField onChange={handleInputChange(props.name)} {...props} className="textComponent" />

The handleChange prop needs to be left out from being forwarded in MUITextField component after it's decorated and passed as onChange prop for MUITextField component.

This can be accomplished using object de-structuring.

const TextComponent = (props) => {
  const {handleChange, ...restProps} = props;
  const handleInputChange = (name) => ({ target }) => {
    handleChange({ [name]: target.value }, target.value);
  };
  return (
    <TextField
        onChange={handleInputChange(props.name)} 
        {...restProps} 
        className="textComponent"
    />
  );
};

Also, leave out onChange prop in the test. It is overriding the decorated onChange prop in TextComponent implementation because restProps will contain another onChange prop.