6

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

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

有没有办法window.onkeydown使用React Test Utils进行测试?如果没有,有没有更好的方法在 mocha for node 中做到这一点?

这是一些说明问题的代码:

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);
    });
});
4

2 回答 2

1

多亏了大卫的评论,我通过忽略事件并将状态设置为测试所需的状态来解决它。我还发现了另一种在未来测试窗口事件的方法。创建一个扩展 EventEmitter 的窗口类,您可以通过 接收 keydown/keyupctrl事件window.emit('keydown',{keyCode: 17})

这是我的_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];
  }
});
于 2016-08-08T15:06:40.523 回答
1

如果你像这样设置你的监听器,window.addEventListener('keydown', myFunc)那么你只需要 test myFunc,你实际上不需要 test发生addEventListener时调用你的函数keydown

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

于 2016-08-06T07:29:30.393 回答