如何测试函数是否在功能性 React 组件中调用 onChange?

Azu*_*Azu 5 testing reactjs jestjs enzyme

我有一个需要测试的简单功能组件。

const Product = () => {
    const handleOnChange = (value) => {
        console.log(value);
    }

    return (
        <div>
            <input type="text" onChange={(e) => {handleOnChange(e.target.value)}} />
        </div>
    )
}
Run Code Online (Sandbox Code Playgroud)

我想测试当输入更改其值时是否调用了“handleOnChange”函数。我试过了:

let wrapper;
beforeEach(() => {
    wrapper = shallow(<Product />);
});
describe('Product interactions', () => {
it('should call handleOnChange function on input change', () => {

  const mockedhandleOnChange = jest.fn(); 
  wrapper.handleOnChange = mockedhandleOnChange;
  wrapper.find('input').simulate('change', {target: {value: 10}});
  expect(mockedhandleOnChange).toHaveBeenCalledTimes(1);    
});
Run Code Online (Sandbox Code Playgroud)

});

当然它不起作用,因为我无法通过“wrapper.handleOnChange”访问该功能。

请帮忙!

muk*_*210 -2

你应该让 React 成为state单一事实来源。目前,input您的程序正在维护其自身的状态。更好的选择是将其用作受控组件。一旦您用作input受控组件,您的程序将如下所示:

class Product extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};
  }
  handleOnChange = (value) => {
    this.setState({ value })
  }

  return (
    <div>
      <input id="input1" type="text" value={this.state.value} onChange={(e) => {handleOnChange(e.target.value)}} />
    </div>
  )
}
Run Code Online (Sandbox Code Playgroud)

input一旦有了上面的代码,验证和测试就会变得更加简单。您需要调用onChangeof input,然后您可以验证状态。您的测试将如下所示:

let wrapper;
beforeEach(() => {
  wrapper = shallow(<Product />);
});
describe('Product interactions', () => {
  it('should call handleOnChange function on input change', () => {
    wrapper.find('#input1').getNode().props.onChange({
      target: { value: '123' }
    });
    expect(wrapper.state().value).toEqual('123');
  });
});
Run Code Online (Sandbox Code Playgroud)