Reactjs中的测试窗口keydown事件

Test window keydown event in Reactjs

本文关键字:keydown 事件 窗口 测试 Reactjs      更新时间:2023-09-26

我正在编写的组件需要根据是否按下ctrl来更改其行为。

我使用window.onkeydown事件,但React Test Utils中的Simulate不允许我针对window调度事件。我也尝试过window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));,但摩卡/节点无法识别KeyboardEvent

有没有一种方法可以使用React test Utils测试window.onkeydown?如果没有,在node的mocha中有更好的方法吗?

这里有一些代码来解决这个问题:

describe('On Keydown', () => {
    it('fires the event', () => {
        // Component
        const Component = class extends React.Component {
            constructor(props) {
                super(props);
                this.state = { key: false };
                window.addEventListener('keydown', e => this.setState({ key: true }));
                window.addEventListener('keyup', e => this.setState({ key: false }));
            }
            render() {
                return <span>test</span>
            };
        };
        // Rendering
        const rendered = renderIntoDocument(<Component/>);
        // Firing event
        expect(rendered.state.key).to.equal(false);
        // Error here
        Simulate.keyDown(window, { keyCode: 17 });
        expect(rendered.state.key).to.equal(true);
    });
});

如果像window.addEventListener('keydown', myFunc)那样设置侦听器,则只需要测试myFunc,而实际上不需要测试当keydown发生时addEventListener调用您的函数。

通过始终将事件绑定到函数(而不是在回调中进行工作(,测试更直接(您正在测试您的代码(,而且您还可以在完成事件侦听器后删除它们。

由于David的评论,我忽略了该事件并将状态设置为测试所需的状态,从而解决了这个问题。我还找到了一种不同的方法来测试将来的窗口事件。创建一个扩展EventEmitter的窗口类,您可以通过window.emit('keydown',{keyCode: 17})接收keydown/keyup事件,如ctrl

这是我的_test_help.js:的代码

import jsdom from 'jsdom';
import chai from 'chai';
import EventEmitter from 'events';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
const windowClass = class extends EventEmitter {
    constructor() {
        super(doc.defaultView);
        this.__defineSetter__('onkeydown', f => this.on('keydown', f));
        this.__defineSetter__('onkeyup', f => this.on('keyup', f));
    }
    addEventListener (e,f) {
        this.on(e,f);
    }
};
const win = new windowClass();
global.document = doc;
global.window = win;
Object.keys(window).forEach((key) => {
  if (!(key in global)) {
    global[key] = window[key];
  }
});