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

Jest测试报错ReferenceError: KeyframeEffect is not defined如何解决?

解决Jest测试中KeyframeEffect未定义的问题

问题背景

在React的Progress组件中,通过useLayoutEffect使用Web Animations API(KeyframeEffect和Animation)实现进度条动画,浏览器运行正常,但执行Jest测试时抛出ReferenceError: KeyframeEffect is not defined错误。原因是当前使用的jsdom环境(jest-environment-jsdom@27.0.6)未实现Web Animations API。

解决方案

方法一:在测试初始化文件中模拟Web Animations API

在setupTests.ts中全局模拟KeyframeEffect和Animation类,让测试代码能正常执行,还可以按需模拟动画行为(比如直接resolvefinished Promise,触发后续的dispatch逻辑):

import '@testing-library/jest-dom';

// 模拟Web Animations API
global.KeyframeEffect = jest.fn(() => ({}));

global.Animation = jest.fn(() => ({
  play: jest.fn(),
  finished: Promise.resolve(), // 直接完成动画,触发then中的回调
}));

方法二:组件内添加环境判断,跳过测试环境的动画逻辑

在组件的useLayoutEffect中,先检查KeyframeEffect是否存在,不存在则不执行动画代码:

useLayoutEffect(()=>{
  if (pid === progressId && typeof KeyframeEffect !== 'undefined') {
    const keyframes = new KeyframeEffect(
      inner.current, 
      [
        { transform: 'scaleX(0%)', transformOrigin: 'left center' }, 
        { transform: 'scaleX(100%)', transformOrigin: 'left center' }
      ],
      { duration: 3000, fill: 'forwards' }
    );
    const anim = new Animation(keyframes, document.timeline);
    anim.play()
    const finish = anim.finished
    finish.then(() => {
      dispatch({
        type: ECarouselActionType.SET_MOVE
      })
    })
  }
}, [progressId])

方法三:升级jsdom版本

较新的jsdom版本(v28及以上)已支持Web Animations API。可以升级jest-environment-jsdom到对应版本,同时调整相关依赖(如jest)的版本,确保兼容性:

yarn upgrade jest-environment-jsdom@^28.0.0 jest@^28.0.0

注意:升级后可能需要调整Jest配置,适配新版本的API变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:19:00