You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jest和Enzyme为React组件的window keydown事件编写单元测试

使用Jest和Enzyme测试ESC键触发unfocus函数的功能

我会分场景带你完成这个测试,你可以根据组件的实际实现来选择对应的方案:

1. 基础场景:组件监听全局document的keydown事件

如果你的组件是通过生命周期(比如useEffect)在挂载时给document添加ESC键监听,那可以这么测:

测试步骤拆解

  • 先用Jest创建一个mock函数作为unfocus props,方便追踪它的调用情况
  • 用Enzyme的mount渲染组件(因为要处理全局事件监听,shallow渲染可能无法覆盖生命周期的副作用)
  • 模拟document上的ESC键按下事件
  • 断言mock函数被正确调用

测试代码示例

import React from 'react';
import { mount } from 'enzyme';
import MyComponent from './MyComponent';

describe('MyComponent ESC key behavior', () => {
  it('triggers unfocus when Escape key is pressed globally', () => {
    // 1. 创建mock的unfocus函数
    const mockUnfocus = jest.fn();

    // 2. 挂载组件并传入mock函数
    mount(<MyComponent unfocus={mockUnfocus} />);

    // 3. 模拟ESC键的keydown事件
    const escKeyEvent = new KeyboardEvent('keydown', { key: 'Escape' });
    document.dispatchEvent(escKeyEvent);

    // 4. 验证函数被调用一次
    expect(mockUnfocus).toHaveBeenCalledTimes(1);
  });

  it('does NOT trigger unfocus when other keys are pressed', () => {
    const mockUnfocus = jest.fn();
    mount(<MyComponent unfocus={mockUnfocus} />);

    // 模拟Enter键按下
    const enterKeyEvent = new KeyboardEvent('keydown', { key: 'Enter' });
    document.dispatchEvent(enterKeyEvent);

    // 验证函数未被调用
    expect(mockUnfocus).not.toHaveBeenCalled();
  });
});

2. 组件内部元素监听keydown的场景

如果你的组件是给内部某个可聚焦元素(比如带tabIndex的div、input)绑定keydown事件,测试方式会略有不同:

假设组件代码示例

import React from 'react';

const MyComponent = ({ unfocus }) => {
  const handleKeyDown = (e) => {
    if (e.key === 'Escape') {
      unfocus();
    }
  };

  return <div tabIndex={0} onKeyDown={handleKeyDown}>Click to focus</div>;
};

对应测试代码

import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';

describe('MyComponent ESC key behavior', () => {
  it('triggers unfocus when Escape key is pressed on the component element', () => {
    const mockUnfocus = jest.fn();
    const wrapper = shallow(<MyComponent unfocus={mockUnfocus} />);

    // 找到目标元素,模拟keydown事件
    wrapper.find('div').simulate('keydown', { key: 'Escape' });

    expect(mockUnfocus).toHaveBeenCalledTimes(1);
  });
});

3. 测试注意事项

  • 若使用React 18+,需要安装适配的Enzyme适配器(比如@wojtekmaj/enzyme-adapter-react-18)并在测试文件头部配置
  • 全局事件测试后建议清理,避免影响其他测试:
    afterEach(() => {
      jest.clearAllMocks();
    });
    
  • 模拟事件时如果需要事件冒泡,记得添加bubbles: true参数:
    const escKeyEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true });
    

内容的提问来源于stack exchange,提问作者Jinto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:33:57