React测试中userEvent触发带涟漪效果按钮时出现element.animate is not a function错误的修复方法
解决
TypeError: element.animate is not a function测试错误 这个问题的核心原因很明确:React Testing Library依赖的jsdom环境并没有实现浏览器原生的Element.animate()方法,而你的按钮组件使用的material-ripple-effects库在触发涟漪动画时调用了这个未实现的API,导致测试抛出错误。
下面给你几个可行的修复方案,按推荐优先级排序:
方案1:全局模拟Element.animate方法(推荐)
在你的测试全局配置文件(比如jest.setup.js)中添加以下代码,给所有DOM元素补上这个mock方法:
// jest.setup.js Element.prototype.animate = jest.fn(() => ({ onfinish: null, play: jest.fn(), }));
然后确保你的jest.config.js中配置了这个setup文件:
// jest.config.js module.exports = { // 其他配置... setupFilesAfterEnv: ['./jest.setup.js'], };
这样所有测试文件都会自动生效,不需要在单个测试里重复写模拟逻辑。
方案2:在单个测试文件中模拟Element.animate
如果你只想在当前测试文件中解决问题,可以在测试代码开头添加:
import React from "react"; import { fireEvent, render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; import userEvent from "@testing-library/user-event"; import App from "../App"; // 模拟Element.animate方法,避免涟漪动画报错 beforeAll(() => { Element.prototype.animate = jest.fn(() => ({ onfinish: null, play: jest.fn(), })); }); test("should render page and navigate to login page", async () => { const user = userEvent.setup(); render(<App />); const mastheadText = screen.getByText( /lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua\. nunc sed blandit libero volutpat\./i ); expect(mastheadText).toBeInTheDocument(); await user.click(screen.getByTestId("navbarLogin")); expect(screen.getByText(/don't have an account\?/i)).toBeInTheDocument(); });
方案3:Mock掉整个涟漪效果库
如果你想完全禁用涟漪效果的测试逻辑,可以直接mock掉material-ripple-effects库:
import React from "react"; import { fireEvent, render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; import userEvent from "@testing-library/user-event"; import App from "../App"; // Mock涟漪效果库,阻止它执行真实的动画逻辑 jest.mock('material-ripple-effects', () => ({ Ripple: jest.fn().mockImplementation(() => ({ create: jest.fn(), applyAnimation: jest.fn(), })) })); test("should render page and navigate to login page", async () => { const user = userEvent.setup(); render(<App />); const mastheadText = screen.getByText( /lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua\. nunc sed blandit libero volutpat\./i ); expect(mastheadText).toBeInTheDocument(); await user.click(screen.getByTestId("navbarLogin")); expect(screen.getByText(/don't have an account\?/i)).toBeInTheDocument(); });
这些方案都能解决你的测试报错问题,你可以根据自己的项目需求选择最合适的方式。
内容的提问来源于stack exchange,提问作者importTurtle
相关产品推荐
相关产品推荐

