在使用 Jest/Enzyme 进行测试期间检测 React 中的合成点击

IT技术 javascript reactjs jestjs enzyme html-input
2021-05-06 00:24:43

我正在用 React 构建一个应用程序。我在<input type="file"/>react引导程序“后面”隐藏了一个文件输入元素 ( ) Button,以便能够控制样式。因此,当单击按钮时,我转身并在文本输入元素上触发合成单击事件,如下所示。

class OpenFileButton extends React.Component {
  ...
  clickHandler() {
    this.refs['input'].click();
  }

  render() {
    return (
      <ButtonGroup>
        <div>
          <input type="file" onChange={this.props.someCallback}
            ref="input" style={{display: 'none'}}/>
          <Button onClick={this.clickHandler}>Open File</Button>
        </div>
      </ButtonGroup>
    );
  }
}

我希望能够用 Jest/Enzyme 测试这个。但是,虽然我可以模拟按钮上的点击事件,但我还没有弄清楚如何检测文件输入元素上的合成点击事件。

我曾尝试使用 Jest/Enzyme 来模拟输入元素上的点击方法。

const component = mount(<OpenFileButton/>);
const fileInput = component.find('input');
const button    = component.find('Button');
fileInput.click = jest.fn();
button.simulate('click');
expect(fileInput.click).toHaveBeenCalled();

但是,以click这种方式嘲笑该方法不起作用。我也无法添加onClick属性,即fileInput.props().onClick = jest.fn()不起作用。

这个问题是关于在代码本身中检测合成点击事件,而不是在测试代码中,因此不相关。

那么,如何使用 Jest/Enzyme 检测 DOM 元素上的(合成)单击事件?

2个回答

<input />或者this.refs.input是 的一个实例HTMLInputElement

然后你可以测试是否HTMLInputElement.prototype.click被调用。

使用 你将会拥有 :

import sinon from 'sinon';
import {mount} from 'enzyme';

const clickInputSpy = sinon.spy(HTMLInputElement.prototype, 'click')
const component = mount(<OpenFileButton/>);

const button    = component.find('Button');

button.simulate('click');
expect(clickInputSpy.called).toBeTruthy();
clickInputSpy.restore();

这里的解决方案涉及监视click我感兴趣的特定文件输入元素方法。因此,我可以检查在按钮元素上模拟单击后是否调用了此 file-input-element-click-spy,如下:

const openFileButtonWrapper = mount(<OpenFileButton/>);
const buttonWrapper = openFileButtonWrapper.find(Button);
const fileInputWrapper = openFileButtonWrapper.find('input [type="file"]');
const fileInput = fileInputWrapper.get(0);
const clickInputSpy = spyOn(fileInput, 'click');
buttonWrapper.simulate('click');
expect(clickInputSpy).toHaveBeenCalled();

@AbdennourTOUMI 的回答使用了 Sinon 的spy方法,它提醒我 Jest 使用了一些 Jasmine 功能,包括它的spyOn方法,这在 Jest 文档中并不明显。因此,即使其他答案最终监视了 _all_ 输入元素,这并不理想,但它确实让我朝着正确的方向前进,所以谢谢你,Adbennour。