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

如何在Enzyme/Jest中测试useEffect内的ESC键关闭模态框逻辑

如何正确测试React模态框的ESC键关闭逻辑

首先,我们来拆解你当前测试代码存在的核心问题:

  • 你用jest.fn()替换了global.document.addEventListener,这直接导致组件里useEffect中定义的实际键盘监听器没有真正绑定到document上。后续触发dispatchEvent时,根本没有对应的回调函数执行,自然无法触发toggleShowModal。
  • 通过jest.spyOn(wrapper.props(), 'toggleShowModal')监听props方法的方式不够可靠,mount后的组件props引用可能和你最初传入的mock函数存在差异,导致监听失效。

下面是修正后的测试方案,能准确验证ESC键关闭模态框的逻辑:

import { mount } from 'enzyme';
import Modal from './Modal'; // 替换为你的Modal组件实际路径

test('triggers toggleShowModal when ESC key is pressed', () => {
  // 1. 创建一个可追踪的mock函数
  const mockToggleShowModal = jest.fn();
  
  // 2. 挂载组件并传入mock函数作为props
  const wrapper = mount(<Modal toggleShowModal={mockToggleShowModal} />);
  
  // 3. 构造ESC键的keydown事件,确保事件能冒泡到document
  const escKeyEvent = new KeyboardEvent('keydown', {
    key: 'Escape',
    keyCode: 27,
    which: 27,
    bubbles: true
  });
  
  // 4. 在document上触发该键盘事件
  document.dispatchEvent(escKeyEvent);
  
  // 5. 断言mock函数被成功调用
  expect(mockToggleShowModal).toHaveBeenCalled();
  
  // 可选验证:卸载组件后,监听器会被移除,不会重复触发
  wrapper.unmount();
  const secondEscEvent = new KeyboardEvent('keydown', { key: 'Escape' });
  document.dispatchEvent(secondEscEvent);
  expect(mockToggleShowModal).toHaveBeenCalledTimes(1);
});

另外,也建议你优化组件代码,让逻辑更严谨:

import React from 'react';

const Modal = ({ toggleShowModal }) => {
  const ESCAPE_KEY_CODE = 27;
  
  React.useEffect(() => {
    const handleEscKey = (e) => {
      // 简化判断逻辑,key是现代浏览器标准,keyCode/which做兼容
      if (e.key === 'Escape' || e.keyCode === ESCAPE_KEY_CODE) {
        toggleShowModal();
      }
    };
    
    document.addEventListener('keydown', handleEscKey);
    // 清理函数确保组件卸载时移除监听器,避免内存泄漏
    return () => document.removeEventListener('keydown', handleEscKey);
  }, [toggleShowModal]); // 加入依赖项,遵循React Hooks规则
  
  return (
    <div className="modal-container">
      {/* 模态框内容 */}
    </div>
  );
};

export default Modal;

几个关键注意事项:

  • 不要mock原生的addEventListener:让组件正常绑定监听器,才能真实模拟用户的键盘操作流程。
  • 事件需设置bubbles: true:确保键盘事件能正确冒泡到document层级,被我们的监听器捕获。
  • 完善useEffect的依赖数组:将toggleShowModal加入依赖项,避免不必要的重渲染和逻辑异常。

内容的提问来源于stack exchange,提问作者Yuridia Larios Aispuro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:52:33