如何用Jest正确测试集成最新Material Web Components的Next.js/React应用?
解决Jest测试Next.js/React + Material Web Components的问题
1. 修复TypeError: this.attachInternals is not a function
方案A:升级jsdom(推荐)
如果你的Jest环境使用的jsdom版本低于20.x,直接升级到最新版——jsdom从20版本开始原生支持attachInternals API,无需手动Mock。
修改package.json中的依赖:
{ "devDependencies": { "jsdom": "^22.0.0", "jest-environment-jsdom": "^29.0.0" } }
执行npm install或yarn install更新依赖。
方案B:安全Mock attachInternals
若无法升级jsdom,避免直接覆盖HTMLElement.prototype引发副作用,改用条件定义或Jest Spy实现:
在Jest配置的setupFilesAfterEnv指定文件(如jest.setup.js)中添加:
// 仅在API不存在时添加,避免覆盖原生实现 if (!HTMLElement.prototype.attachInternals) { Object.defineProperty(HTMLElement.prototype, 'attachInternals', { value: function() { return { setFormValue: () => {}, setValidity: () => {}, checkValidity: () => true, reportValidity: () => true }; }, configurable: true, writable: true }); }
或者在单个测试文件中局部Mock,测试后恢复:
beforeAll(() => { jest.spyOn(HTMLElement.prototype, 'attachInternals') .mockReturnValue({ setFormValue: jest.fn(), setValidity: jest.fn() }); }); afterAll(() => { jest.restoreAllMocks(); });
2. 解决按钮属性(name/role)丢失问题
确保Material Web Components正确注册
在Jest setup文件中导入你使用的MWC组件,保证自定义元素被正确定义:
// jest.setup.js import '@material/web/button/filled-button.js'; import '@material/web/button/outlined-button.js'; // 其他用到的MWC组件
验证React属性传递逻辑
确保在React组件中正确给MWC按钮传递属性:
// 示例组件 import { FilledButton } from '@material/web/button/filled-button.js'; export default function SignInButton() { return ( <FilledButton name="Redirect to Sign in" role="link" onClick={() => {/* 业务逻辑 */}} > Sign In </FilledButton> ); }
测试时灵活选择查询方式
若getByRole查询仍有问题,可先用getByTestId作为临时方案,同时排查属性丢失原因:
// 组件中添加测试标识 <FilledButton data-testid="sign-in-link" name="Redirect to Sign in" role="link" > Sign In </FilledButton> // 测试用例 test('renders sign in link with correct attributes', () => { render(<SignInButton />); const button = screen.getByTestId('sign-in-link'); expect(button).toHaveAttribute('name', 'Redirect to Sign in'); expect(button).toHaveAttribute('role', 'link'); });
额外注意事项
- 优先选择升级依赖而非全局修改原生DOM原型,减少测试环境副作用
- 确保Jest配置中
testEnvironment设置为jsdom - 若使用TypeScript,可添加
@types/web补全自定义元素的类型定义
内容的提问来源于stack exchange,提问作者Gerson Yesid Lazaro
相关产品推荐
相关产品推荐

