Reactjs中的测试窗口keydown事件

时间:2016-08-05 20:34:54

标签: javascript reactjs reactjs-testutils

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

我使用window.onkeydown事件但 React Test Utils 中的Simulate不允许我针对window发送事件。我也尝试了window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));,但是mocha / node无法识别KeyboardEvent

有没有办法使用 React Test Utils 测试window.onkeydown?如果没有,有没有更好的方法在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);
    });
});

2 个答案:

答案 0 :(得分:1)

如果您将听众设置为window.addEventListener('keydown', myFunc),那么您只需要测试myFunc,当addEventListener keydown时,您实际上不需要测试$('#your_image_for_the_scroll').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); }); 调用您的函数发生。

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

答案 1 :(得分:1)

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

这是我 _test_helper.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];
  }
});