在JEST单元测试中模拟文档的keydown事件

22

如何使用JEST对附加了到文档的keydown监听器的组件进行单元测试?我该如何在JEST中模拟文档上的keydown事件?由于监听器需要响应键盘动作而不考虑聚焦元素,因此我需要将其附加在文档上。

编辑:问题在于如何在文档或document.body上模拟事件。所有示例都涉及实际的DOM节点,这很好,但文档不是。

目前正在尝试以下操作:

TestUtils.Simulate.keyDown(document, {keyCode : 37}); // handler not invoked

可能是React的TestUtils.Simulate.keyDown不起作用的重复问题。 - Henrik Andersson
3个回答

45

我遇到了完全相同的问题,但不幸的是无法找到如何使用TestUtils.Simulate解决它的详细信息。然而这个问题给了我一个想法,直接在我的jest测试中使用.dispatchEventKeyboardEvent来解决:

var event = new KeyboardEvent('keydown', {'keyCode': 37});
document.dispatchEvent(event);

您可以在此处找到有关 KeyboardEvent 的详细信息:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent


感谢您的回答。 - tiffon
4
只有将'keydown'更改为'keypress'时,它才对我起作用。 - paddotk
1
截至2020年和最新版本的Jest,如果我使用global.dispatchEvent而不是window.dispatchEvent,这对我有效。 - daniero
此外,事件数据中可能需要 bubbles: true - jomido

4

在挂载组件之前,您还可以将整个 document.eventListener 替换为模拟函数:

let events;
document.addEventListener = jest.fn((event, cb) => {
  events[event] = cb;
});

在挂载之后通过调用events[event]来模拟事件,例如:

events.keydown({ keyCode: 37 })

如果你有很多处理DOM事件的测试,那么在beforeEach()函数中完成第一部分会非常方便。


1

根据 @Iris Schaffer 的回答,如果您的代码使用了 ctrl/alt/shift 键,则需要初始化它们,并模拟实现 KeyboardEvent 上的 getModifierState 方法。

const keyboardEvent = new KeyboardEvent('keydown', { keyCode, shiftKey, altKey, ctrlKey });
jest.spyOn(keyboardEvent, 'getModifierState').mockImplementation((modifier) => {
     switch (modifier) {
          case 'Alt':
               return altKey;
          case 'Control':
               return ctrlKey;
          case 'Shift':
               return shiftKey;
     }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接