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
相关产品推荐
相关产品推荐

