如何在网页中独立使用jest-dom?解决带参匹配器报错问题
解决网页环境中jest-dom匹配器
this.equals报错问题 问题根源
jest-dom的匹配器设计时依赖Jest的expect上下文环境,this.equals是Jest提供的断言核心比较方法。直接将匹配器挂载到window调用时,this指向window而非Jest的上下文对象,导致缺少该方法报错。
解决方案一:手动模拟Jest上下文并绑定匹配器
手动创建包含equals方法的上下文对象,将匹配器的this绑定到该对象,适配无复杂依赖的匹配器:
// 模拟Jest断言所需的核心上下文方法 const jestContext = { // 实现基础相等判断,与Jest的equals逻辑对齐 equals: (a, b) => Object.is(a, b), // 如需支持其他匹配器依赖的方法(如utils),可按需补充 }; // 包装单个匹配器,绑定上下文 function wrapMatcher(matcher) { return (...args) => matcher.call(jestContext, ...args); } // 导入并批量包装所有jest-dom匹配器 import matchers from '@testing-library/jest-dom/matchers'; window.jestDomMatchers = Object.fromEntries( Object.entries(matchers).map(([name, matcher]) => [name, wrapMatcher(matcher)]) );
使用示例:
const btn = document.getElementById('test-btn'); // 调用包装后的匹配器 const result = window.jestDomMatchers.toHaveAccessibleName(btn, '提交'); console.log(result.pass); // 输出true/false
解决方案二:使用@jest/expect提供完整上下文
通过@jest/expect包引入Jest的核心断言环境,该方案能完整兼容所有jest-dom匹配器(包括链式调用如.not):
- 先安装依赖:
npm install @jest/expect --save
- 编写封装代码:
import { expect } from '@jest/expect'; import matchers from '@testing-library/jest-dom/matchers'; // 将jest-dom匹配器注册到Jest的expect系统中 expect.extend(matchers); // 封装可在网页环境调用的断言函数 window.jestDomAssert = (element, matcherName, ...args) => { try { expect(element)[matcherName](...args); return { pass: true, message: '断言通过' }; } catch (err) { return { pass: false, message: err.message }; } };
使用示例:
const input = document.getElementById('username-input'); // 执行带参数的匹配器断言 const assertResult = window.jestDomAssert(input, 'toHaveAccessibleName', '用户名'); if (!assertResult.pass) { console.error(assertResult.message); } // 扩展支持链式调用(如.not) window.jestDomAssert = (element, matcherChain, ...args) => { try { let expectInstance = expect(element); // 处理链式调用,比如['not', 'toHaveTextContent'] matcherChain.forEach(method => { expectInstance = expectInstance[method]; }); expectInstance(...args); return { pass: true, message: '断言通过' }; } catch (err) { return { pass: false, message: err.message }; } }; // 调用.not链式断言 const notResult = window.jestDomAssert(btn, ['not', 'toBeDisabled']);
方案对比
- 方案一:体积小,适合只用到简单匹配器的场景,但无法支持依赖Jest其他上下文方法的复杂匹配器。
- 方案二:兼容性最好,能支持所有jest-dom匹配器功能,但会引入
@jest/expect的额外体积。
内容的提问来源于stack exchange,提问作者Luís Soares
相关产品推荐
相关产品推荐

