You need to enable JavaScript to run this app. Jest单元测试中如何调用requestAnimationFrame的实际回调函数
优惠活动
大模型
产品
解决方案
定价
更多

Jest单元测试中如何调用requestAnimationFrame的实际回调函数

触发mock的requestAnimationFrame回调的测试方法

核心逻辑

当你将window.requestAnimationFrame mock为jest.fn()后,mock实例会自动存储所有调用时传入的参数,也就是你传入的回调函数。你只需要手动提取该回调并执行,就能触发回调内部的所有逻辑,完成断言。

具体操作步骤

场景1:手动初始化纯jest.fn() mock

即你主动写了window.requestAnimationFrame = jest.fn()的情况:

  • 触发业务逻辑执行,让代码走到调用requestAnimationFrame的分支
  • 从mock的调用记录中提取回调:const rafCallback = window.requestAnimationFrame.mock.calls[0][0]
    • mock.calls是所有raf调用的参数集合,每一项对应一次调用的入参数组,因为raf只有1个参数(回调),所以取第0个元素即可
  • 直接执行回调:rafCallback()
  • 此时即可正常断言回调内部的process、clearTimeout等逻辑的执行情况

场景2:使用Jest fake timers 统一模拟异步定时器

如果你已经调用过jest.useFakeTimers(),Jest会自动接管包括requestAnimationFrame在内的所有定时器/动画API,无需手动提取回调:

  • 触发业务逻辑执行后,直接调用jest.runAllTimers(),会自动执行所有待运行的raf、setTimeout、setInterval回调
  • 也可通过jest.advanceTimersByTime(16)模拟16ms(单帧标准时长)的时间流逝,精准触发单帧对应的raf回调

完整测试用例示例

// 先mock业务依赖
const mockProcess = jest.fn();
window.clearTimeout = jest.fn();
// 引入业务逻辑(需在依赖mock完成后引入)
import { yourBusinessLogicFn } from './your-code-path';

describe('raf回调逻辑测试', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    // 初始化raf mock
    window.requestAnimationFrame = jest.fn();
    // 执行业务逻辑,触发raf调用
    yourBusinessLogicFn();
  });

  test('raf回调执行时触发对应业务逻辑', () => {
    // 断言raf被正确调用
    expect(window.requestAnimationFrame).toHaveBeenCalledTimes(1);
    // 提取并执行回调
    const rafCallback = window.requestAnimationFrame.mock.calls[0][0];
    rafCallback();
    // 断言内部逻辑执行
    expect(mockProcess).toHaveBeenCalledWith('postProcess');
    expect(window.clearTimeout).toHaveBeenCalled();
  });
});

注意事项

  • 如果业务逻辑中多次调用requestAnimationFrame,可通过mock.calls的不同下标对应提取不同调用的回调,比如第二次调用的回调为window.requestAnimationFrame.mock.calls[1][0]
  • 执行回调前注意重置其他mock的调用记录,避免上一个测试用例的调用记录干扰断言结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 06:54:04