在 Reactjs 中测试 window keydown 事件
Test window keydown event in Reactjs
我正在编写的组件需要根据是否按下 ctrl 来更改其行为。
我使用 window.onkeydown
事件,但是 React Test Utils 中的 Simulate
不允许我针对 window
发送事件。我也试过 window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));
但 mocha/node 无法识别 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
,你实际上不需要测试 addEventListener
在 [= 时调用你的函数13=] 发生了。
通过始终将事件绑定到函数(而不是在回调中进行工作),测试更加直接(您正在测试 您的 代码)并且您还可以在以下情况下删除事件侦听器你已经完成了它们。
由于 David 的评论,我通过忽略事件并将状态设置为测试所需的状态来解决它。我还发现了一种不同的方法来测试 window 事件。创建扩展 EventEmitter 的 window class,您可以接收 keydown/keyup 事件,例如 ctrl 到 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];
}
});
我正在编写的组件需要根据是否按下 ctrl 来更改其行为。
我使用 window.onkeydown
事件,但是 React Test Utils 中的 Simulate
不允许我针对 window
发送事件。我也试过 window.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 17 }));
但 mocha/node 无法识别 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
,你实际上不需要测试 addEventListener
在 [= 时调用你的函数13=] 发生了。
通过始终将事件绑定到函数(而不是在回调中进行工作),测试更加直接(您正在测试 您的 代码)并且您还可以在以下情况下删除事件侦听器你已经完成了它们。
由于 David 的评论,我通过忽略事件并将状态设置为测试所需的状态来解决它。我还发现了一种不同的方法来测试 window 事件。创建扩展 EventEmitter 的 window class,您可以接收 keydown/keyup 事件,例如 ctrl 到 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];
}
});