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

Detect synthetic click in React during testing with Jest/Enzyme

我正在使用 React 构建应用程序。我隐藏了一个文件输入元素 (<input type="file"/>) "behind" 一个 react-bootstrap 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() 不起作用。

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

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

<input />this.refs.inputHTMLInputElement.

的实例

然后你可以测试是否调用了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();

const clickInputSpy = sinon.spy(HTMLInputElement.prototype, 'click');


console.log(
 'Is <input /> clicked ? ', clickInputSpy.called 
);
document.querySelector('input').click();


console.log(
 'Is <input /> clicked ? ', clickInputSpy.called 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


<script src="https://cdnjs.cloudflare.com/ajax/libs/sinon.js/1.15.4/sinon.min.js"></script>

<input />

此处的解决方案涉及监视我感兴趣的特定文件输入元素的 click 方法。因此我可以检查是否调用了此文件输入元素单击间谍在button元素上模拟点击后,如下:

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。