用Jest酶测试输入组件

时间:2019-09-27 04:52:29

标签: reactjs jestjs material-ui enzyme

我有一个简单的Input组件,我想用酶来测试。

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;

我的测试用例看起来像这样

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');
});

在运行测试用例时,出现错误提示

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.

如何测试是否用正确的数据调用了handleChangeMock函数?

1 个答案:

答案 0 :(得分:0)

在您的测试中,这些道具会传递给TextComponent

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

但是在TextComponent实现中,所有这些道具在装饰MUITextField道具之后都在handleChange中转发。

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

handleChange道具在装饰并作为MUITextField组件的onChange道具传递后,需要从MUITextField组件中转发出去。

这可以通过对象分解来实现。

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"
    />
  );
};

此外,在测试中省略onChange道具。它会覆盖onChange实现中修饰的TextComponent道具,因为restProps将包含另一个onChange道具。