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

Jest测试中如何正确mock window对象的ontouchstart事件

问题原因

你之前的写法报错,核心原因是 Jest 默认使用的 jsdom 测试环境初始化时,window 对象上默认不存在ontouchstart属性,而jest.spyOn只能监听对象上已经存在的属性,自然会触发「属性不存在」的编译/运行错误。
另外你的待测试逻辑是通过'ontouchstart' in window做存在性判断,根本不需要对属性做方法实现的mock,只要让属性挂载到window上就能命中对应判断分支。

可直接运行的测试代码

1. 测试命中ontouchstart判断的分支

it('returns true when ontouchstart exists on window', () => {
  // 直接给window挂载属性即可,in操作符只判断属性是否存在,和具体值无关
  window.ontouchstart = jest.fn();
  
  expect(main()).toBe(true);
  
  // 测试完成后删除属性,避免污染其他测试用例
  delete window.ontouchstart;
});

2. 测试命中maxTouchPoints判断的分支

注意navigator.maxTouchPoints是只读属性,不能直接赋值修改,需要通过Object.defineProperty重写:

it('returns true when navigator.maxTouchPoints is greater than 0', () => {
  // 先清除ontouchstart避免分支判断干扰
  delete window.ontouchstart;

  // 重写只读属性
  Object.defineProperty(navigator, 'maxTouchPoints', {
    configurable: true,
    value: 2
  });

  expect(main()).toBe(true);

  // 测试完成还原默认值
  Object.defineProperty(navigator, 'maxTouchPoints', {
    configurable: true,
    value: 0
  });
});

3. 测试无触摸支持的返回false分支

it('returns false when no touch support is detected', () => {
  delete window.ontouchstart;
  Object.defineProperty(navigator, 'maxTouchPoints', {
    configurable: true,
    value: 0
  });

  expect(main()).toBe(false);
});
注意事项
  • 如果你使用TypeScript编写测试,给window挂载ontouchstart时可能报类型错误,可在对应行加// @ts-ignore忽略,或者在测试文件的全局类型声明里扩展Window接口添加ontouchstart的类型定义即可。
  • 所有手动修改的window、navigator属性一定要在用例执行完成后还原/删除,否则会污染同文件下的其他测试用例,导致用例结果偶发不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:51:31