ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何单元测试React动画组件?react-keyframes搭配Jest fake timers完整教程

如何单元测试React动画组件?react-keyframes搭配Jest fake timers完整教程 如何单元测试React动画组件react-keyframes搭配Jest fake timers完整教程【免费下载链接】react-keyframesCreate frame-based animations in React项目地址: https://gitcode.com/gh_mirrors/re/react-keyframesreact-keyframes 是一个用于在 React 中创建帧动画frame-based animations的组件库用Keyframes包裹若干Frame每一帧按duration指定的毫秒数依次展示内容。像这类依赖时间推进的 React 动画组件单元测试最容易踩坑——直接setTimeout等待会慢硬等又会不稳定flaky。本文将结合该项目自带测试用例讲解如何用 Jest fake timers 把时间变成可控变量快速、确定地完成动画组件测试。为什么动画组件测试总是不稳定真实定时器测试有两个经典问题慢一帧 100ms、动画 10 帧单条用例就要等 1 秒以上不可靠CI 环境慢一点断言就可能错过中间帧。fake timers虚拟定时器的思路是拦截setTimeout让时间由测试代码手动拨快。这样 100ms 的帧在测试里瞬间完成且每次运行结果完全一致。react-keyframes 逐帧动画的实现原理理解源码是写好测试的前提。核心实现在 packages/react-keyframes/src/index.tsKeyframes类在componentDidMount/componentDidUpdate中调用requestNextFrame()requestNextFrame()通过waitForDelay()读取当前帧的duration然后setTimeout(fn, delay)切换到下一帧组件卸载时会clearTimeout避免内存泄漏。正因为动画推进完全依赖setTimeoutfake timers 才能接管整个过程——这是它能被稳定测试的根本原因。最小用法参考function MyComponent() { return ( Keyframes Frame duration{500}This/Frame Frame duration{500}This is/Frame /Keyframes ); }三步搭建测试环境Jest Testing Library项目根目录 package.json 中已备好测试依赖jest、ts-jest、testing-library/react、testing-library/jest-dom。第一步配置 Jest 使用 TypeScript 预设。整个配置就一行见 jest.config.jsmodule.exports { preset: ts-jest };第二步测试文件放在test/目录直接import源码目录下的组件无需先构建。第三步运行根目录的test脚本即jest即可。项目采用 lerna workspaces 管理包见 lerna.json。核心实战用 advanceTimersByTime 逐帧推进动画完整示例在 test/index.test.tsx逻辑只有四步1️⃣ 在测试顶部开启虚拟定时器必须在渲染前jest.useFakeTimers();2️⃣ 渲染组件断言第一帧const { container } render( Keyframes Frame duration{100}foo/Frame Frame duration{200}bar/Frame Framebaz/Frame /Keyframes ); expect(container.childNodes[0].textContent).toBe(foo);3️⃣ 手动拨快时间帧就会跟着切换jest.advanceTimersByTime(100); // 经过 100ms进入第 2 帧 expect(container.childNodes[0].textContent).toBe(bar); jest.advanceTimersByTime(200); // 再经过 200ms进入第 3 帧 expect(container.childNodes[0].textContent).toBe(baz);4️⃣ 注意一个细节每帧的duration决定进入下一帧的延迟所以advanceTimersByTime的参数必须和对应帧的duration对齐拨少了帧不会切换拨多了只是快进到同一帧上。整个过程不等待任何真实时间测试瞬间完成 ✅如何验证自定义渲染组件与样式Keyframes的component属性控制它渲染成什么元素默认span其余自定义属性会透传给渲染结果。官方测试同样覆盖了这一点const { container } render( Keyframes componentpre classNamewoot Framefoo/Frame Framebar/Frame /Keyframes ); expect(container.childNodes[0].nodeName).toBe(PRE); expect(container.childNodes[0]).toHaveClass(woot);断言nodeName验证标签替换是否生效toHaveClass验证样式透传——两者都是不依赖时间的一次性断言无需拨动定时器。4 个常见坑位与避坑方案坑现象解决方案忘记开启 fake timers测试真实等待或时序错乱在render之前调用jest.useFakeTimers()duration漏传帧瞬间切换断言第 2 帧失败未传duration时延迟默认为 0ms测试数据要显式给出拨快时间与帧时长不对齐停在中间帧断言不通过每次advanceTimersByTime(n)的 n 对齐当前帧duration多帧动画只断言了首尾漏测中间帧与卸载清理每切一帧断言一次必要时渲染后卸载组件验证clearTimeout无报错 进阶建议如果项目里同时存在必须真实计时的测试可对单个测试文件用jest.useFakeTimers()其余文件保持真实定时器避免全局污染。小结用 react-keyframes 这类基于setTimeout的动画组件做单元测试套路可以总结为三句话开启jest.useFakeTimers()→render后断言当前帧 → 用advanceTimersByTime(duration)逐帧推进并断言。掌握了这套组合拳React 动画组件测试既快又稳。相关参考文件组件源码packages/react-keyframes/src/index.ts测试用例test/index.test.tsxJest 配置jest.config.js包元信息与脚本packages/react-keyframes/package.json【免费下载链接】react-keyframesCreate frame-based animations in React项目地址: https://gitcode.com/gh_mirrors/re/react-keyframes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表