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

如何使用Jest正确测试Framer Motion动画执行后的组件样式?

解决方案

测试失败的核心原因是framer-motion的动画为异步调度,组件首次渲染完成时动画逻辑还未执行,因此DOM上的transform样式还未更新。以下是几种符合最佳实践的可行方案:

方案1:使用RTL的waitFor异步断言

这是改动最小的方案,不需要修改任何业务代码或全局配置,仅需调整测试逻辑,通过waitFor轮询断言条件,而非固定时长等待:

import { waitFor, screen, render } from '@testing-library/react';

test("Component when isSelected highlights the image", async () => {
  render(<Previewer isSelected />);
  const image = screen.getByRole("img");
  await waitFor(() => {
    expect(image).toHaveStyle("transform: scale(1.5) translateZ(0)");
  });
});

waitFor会在条件满足后立刻终止轮询,默认超时时间为1000ms,可通过第二个参数自定义超时配置,完全符合前端测试最佳实践。

方案2:测试环境全局Mock framer-motion

如果项目中有大量涉及framer-motion的测试用例,可以在测试环境全局配置Mock,让所有动画直接跳转到最终状态,无需等待,完全不影响生产环境的动画效果:

步骤1:配置jest全局Mock

在jest的setup文件(通常为jest.setup.js/jest.setup.ts)中添加如下代码:

jest.mock('framer-motion', () => {
  const original = jest.requireActual('framer-motion');
  return {
    ...original,
    motion: new Proxy(original.motion, {
      get(target, key) {
        const originalComponent = target[key];
        return (props) => originalComponent({ ...props, initial: false });
      }
    })
  };
});

这个Mock会给测试环境中所有的motion组件自动添加initial={false}属性,动画会立刻应用最终样式,你原来的同步测试代码不需要任何修改即可运行。

方案3:使用framer-motion官方测试Mock

framer-motion官方提供了专门用于测试的Mock包,不需要自己手写Mock逻辑,兼容性最好:

步骤1:修改jest配置

在jest.config.js中添加模块映射:

module.exports = {
  moduleNameMapper: {
    'framer-motion': 'framer-motion/mock',
  },
}

配置完成后所有测试用例中的framer-motion动画都会直接应用最终状态,不需要额外的异步等待逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 11:45:02