如何在React Jest测试中验证鼠标事件的clientY属性
问题场景与代码
以下是导航栏组件中用于关闭下拉菜单的useEffect逻辑,导航栏固定高度50px,需求是用户点击导航栏外部(clientY > 50)时,关闭所有激活的下拉菜单:
useEffect(() => { const maybeHandler = (event: MouseEvent) => { menuData.forEach((el) => { if (el.hasActiveDropdown && event.clientY > 50) { handleCloseDropDown(); // handleDropDown('0'); } }); }; document.addEventListener('mousedown', maybeHandler); return () => document.removeEventListener('mousedown', maybeHandler); }, [handleCloseDropDown, menuData]);
遇到的问题:无法在Jest测试中模拟event.clientY属性,验证点击区域的逻辑。
解决方案
在Jest中可以手动构造包含指定clientY的MouseEvent对象,触发document上的mousedown事件来覆盖两种场景:
1. 测试点击导航栏外部(关闭下拉)
import { render, fireEvent } from '@testing-library/react'; import YourNavBarComponent from './YourNavBarComponent'; test('点击导航栏外部时触发下拉菜单关闭', () => { // 模拟关闭函数 const mockClose = jest.fn(); // 传入激活状态的菜单数据 const mockMenuData = [{ hasActiveDropdown: true }]; render(<YourNavBarComponent handleCloseDropDown={mockClose} menuData={mockMenuData} />); // 构造clientY > 50的点击事件 const outsideClick = new MouseEvent('mousedown', { clientY: 60 }); fireEvent(document, outsideClick); // 验证关闭函数被调用 expect(mockClose).toHaveBeenCalledTimes(1); });
2. 测试点击导航栏内部(不关闭下拉)
test('点击导航栏内部时不触发下拉菜单关闭', () => { const mockClose = jest.fn(); const mockMenuData = [{ hasActiveDropdown: true }]; render(<YourNavBarComponent handleCloseDropDown={mockClose} menuData={mockMenuData} />); // 构造clientY ≤ 50的点击事件 const insideClick = new MouseEvent('mousedown', { clientY: 30 }); fireEvent(document, insideClick); // 验证关闭函数未被调用 expect(mockClose).not.toHaveBeenCalled(); });
关键说明
- 直接通过
new MouseEvent()创建自定义事件,手动指定clientY属性值,完全符合浏览器原生事件的结构 - 测试时要确保传入的
menuData包含hasActiveDropdown: true的项,这样才能触发判断逻辑 - 使用
fireEvent触发document上的事件,模拟全局点击行为
内容的提问来源于stack exchange,提问作者gopi mudumal
相关产品推荐
相关产品推荐

