Mocha 测试移动端 React 组件时怎么处理触摸事件?
我在用 Mocha + JSDOM 测试一个移动端的 React 滑动组件,但模拟 touchstart 事件根本没反应,控制台也不报错,本地真机调试是正常的。是不是 JSDOM 不支持 TouchEvent?
我试过用 fireEvent.touchStart(配合 @testing-library/react),也试过手动创建 TouchEvent,但组件里的 onTouchStart 回调就是不触发。下面是我组件里的一小段代码:
const SwipeBox = () => {
const handleTouchStart = (e) => {
console.log('touch started', e.touches[0].clientX);
};
return (
<div
onTouchStart={handleTouchStart}
style={{ width: '100%', height: '200px', background: '#eee' }}
/>
);
};
onTouchStart自然不会触发。但问题关键不在 JSDOM,而在于你用的测试环境和库组合。React 的事件系统会把 touch 事件挂到 DOM 上,但如果你用的是旧版 JSDOM(比如 v16.x 之前),它连
document.createEvent('TouchEvent')都不支持,或者创建出来没touches属性,自然没反应。最简单的办法是升级到 JSDOM ≥ 22.1.0,然后在测试前注入 polyfill:
然后在 mocha 启动参数里加
--require ./setupTests.js。不过更推荐的是直接用
@testing-library/user-event的userEvent.pointer,它会自动处理 touch/mouse 的兼容:如果还是不行,你也可以手动构造一个 fake touch 对象,让 React 的事件系统能识别:
注意:上面这段必须在 JSDOM 支持
TouchEvent的前提下才有效,所以还是得先升级环境。总之,核心就是:别指望 JSDOM 天生支持 touch,要么升级它,要么用 user-event 的 pointer 模拟,要么自己打补丁。真机没问题是因为手机浏览器有完整的 Touch API,而测试环境得你手动补上。