React自动播放视频着陆页Jest测试报错及解决尝试
解决React视频自动播放的Jest测试报错问题
问题根源
Jest基于jsdom运行测试,而jsdom并未实现HTMLMediaElement.prototype.play等媒体API的真实逻辑;同时浏览器中play()方法实际返回Promise,你之前的mock返回true,导致组件中调用play().then()时触发TypeError: promise.then is not a function错误。
解决方案1:单测试用例中Mock媒体方法
直接在测试里mockplay和pause方法,让它们返回resolved Promise,同时可验证方法是否被调用:
import { render, screen } from '@testing-library/react'; import App from './App'; describe("Home Page", () => { test('Rendering landing page', async () => { // Mock play方法返回resolved Promise const playSpy = jest.spyOn(window.HTMLMediaElement.prototype, 'play') .mockImplementation(() => Promise.resolve()); // 按需mock pause方法 jest.spyOn(window.HTMLMediaElement.prototype, 'pause') .mockImplementation(() => Promise.resolve()); render(<App />); // 验证页面元素 const signinLink = screen.getAllByText('Signin')[0]; expect(signinLink.href).toContain('/signin-login'); // 可选:验证play方法是否被自动调用 expect(playSpy).toHaveBeenCalled(); // 清理mock,避免影响其他测试 jest.restoreAllMocks(); }); });
解决方案2:全局配置Mock(推荐)
如果多个测试都涉及媒体元素,可在src/setupTests.js中全局配置mock,无需每个测试重复编写:
// src/setupTests.js // 全局mock HTMLMediaElement的play和pause方法 Object.defineProperty(window.HTMLMediaElement.prototype, 'play', { writable: true, value: jest.fn().mockImplementation(() => Promise.resolve()), }); Object.defineProperty(window.HTMLMediaElement.prototype, 'pause', { writable: true, value: jest.fn().mockImplementation(() => Promise.resolve()), });
之后你的测试文件可以简化为:
import { render, screen } from '@testing-library/react'; import App from './App'; describe("Home Page", () => { test('Rendering landing page', async () => { render(<App />); const signinLink = screen.getAllByText('Signin')[0]; expect(signinLink.href).toContain('/signin-login'); }); });
内容的提问来源于stack exchange,提问作者The Old County
相关产品推荐
相关产品推荐

