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

如何使用Jest测试Nuxt应用的自定义横向滚动功能

Nuxt 自定义横向滚动功能的 Jest 测试方案

整体逻辑拆成两个独立模块测试,完全覆盖功能链路,不需要复杂的DOM模拟:

  • 工具函数层:对~/helpers中三个滚动相关函数做独立单元测试,验证单个函数的行为正确性
  • 组件绑定层:对首页组件做挂载/卸载测试,验证滚动事件的绑定、解绑逻辑和生命周期钩子匹配

前置准备

  • Nuxt项目默认集成jsdom测试环境,自带window、document全局对象,无需额外安装DOM模拟库
  • 提前mock~/constants中的SCROLL_SPEED为固定值(比如50),方便计算滚动偏移量
  • 每个用例执行前调用jest.clearAllMocks()清空所有mock调用记录,避免跨用例的状态污染

工具函数单测(helpers.test.js)

先做基础的模块mock:

//  mock常量,固定滚动速度方便断言
jest.mock('~/constants', () => ({
  SCROLL_SPEED: 50
}))
import {
  scrollHorizontally,
  enableCustomScrolling,
  disableCustomScrolling
} from '~/helpers'

测试 enableCustomScrolling

  • 核心验证点:调用函数时,会给window实例绑定两个跨浏览器兼容的滚轮事件(mousewheel、DOMMouseScroll),绑定的回调和传入参数完全一致
  • 测试步骤:
    • 把window.addEventListener mock为jest.fn()
    • 构造假的滚动回调fakeHandler = jest.fn()
    • 调用enableCustomScrolling(fakeHandler)
    • 断言:window.addEventListener 共调用2次,第一次参数为('mousewheel', fakeHandler),第二次为('DOMMouseScroll', fakeHandler)

    可选补充:如果项目需要兼容IE6-8,可模拟window不支持addEventListener的场景,验证attachEvent分支的逻辑

测试 disableCustomScrolling

  • 核心验证点:调用函数时,会移除之前绑定的两个滚轮事件,移除的回调和传入参数完全一致
  • 测试步骤:
    • 把window.removeEventListener mock为jest.fn()
    • 复用上面的fakeHandler
    • 调用disableCustomScrolling(fakeHandler)
    • 断言:window.removeEventListener 共调用2次,分别对应mousewheel、DOMMouseScroll两个事件,回调匹配

测试核心逻辑 scrollHorizontally

每个用例执行前重置两个DOM的scrollLeft初始值为0,保证初始状态一致,覆盖以下场景:

  • 场景1:Chrome/Edge/Safari 正向滚轮(wheelDelta=1)
    • 构造模拟事件:{ wheelDelta: 1, preventDefault: jest.fn() }
    • 调用scrollHorizontally(mockEvent)
    • 断言:
      • document.documentElement.scrollLeft = -50
      • document.body.scrollLeft = -50
      • 事件的preventDefault被调用,阻止默认纵向滚动
  • 场景2:Chrome/Edge/Safari 反向滚轮(wheelDelta=-1)
    • 构造模拟事件:{ wheelDelta: -1, preventDefault: jest.fn() }
    • 调用函数后断言两个scrollLeft值均为50
  • 场景3:Firefox 兼容场景(用detail传递滚轮值)
    • 构造模拟事件:{ detail: 1, preventDefault: jest.fn() }
    • 调用函数后断言两个scrollLeft值均为-50
  • 场景4:IE 兼容兜底(window.event全局事件)
    • 给全局window.event赋值上述正向滚轮的模拟事件,调用函数时不传参数,验证滚动逻辑正常执行

首页组件测试(index.test.js)

这部分不需要跑真实的滚动逻辑,只需要验证生命周期的绑定关系,因此提前把~/helpers整个模块mock掉,避免真实事件绑定污染全局测试环境:

// 完整mock helpers模块
jest.mock('~/helpers', () => ({
  scrollHorizontally: jest.fn(),
  enableCustomScrolling: jest.fn(),
  disableCustomScrolling: jest.fn()
}))
import { mount } from '@vue/test-utils'
import HomePage from '~/pages/index.vue'
import {
  enableCustomScrolling,
  disableCustomScrolling,
  scrollHorizontally
} from '~/helpers'

测试用例:

  • 验证beforeMount阶段:挂载组件后,断言enableCustomScrolling被调用,传入的参数就是导出的scrollHorizontally(组件模板是占位文本,和滚动逻辑无关,不需要校验DOM渲染结果)
  • 验证beforeDestroy阶段:组件挂载完成后调用wrapper.destroy(),断言disableCustomScrolling被调用,传入的参数同样是scrollHorizontally

常见坑点

  • jsdom环境下的scrollLeft属性是可写的,不需要额外做DOM模拟,直接赋值初始值即可
  • 不要在测试中触发真实的浏览器滚动行为,所有DOM状态变化都要显式重置
  • 如果遇到事件对象的兼容问题,可以根据项目实际支持的浏览器范围,裁剪不需要的兼容分支测试,减少冗余用例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 03:57:02