Jest中匹配非Object构造函数生成对象的最优方案问询
解决Jest中类实例与字面量对象精确匹配的问题
针对你遇到的Jest测试场景,这里有几个实用的解决方案,按推荐程度排序:
1. 自定义Jest匹配器(最推荐)
自定义一个专门用于精确匹配对象属性的匹配器,忽略构造函数差异,只校验所有属性的键和值是否完全一致。
在你的测试文件或Jest全局配置文件(比如setupFilesAfterEnv指定的文件)中添加以下代码:
expect.extend({ toMatchExactProperties(received, expected) { // 将接收值和期望值都转为纯对象(忽略原型) const receivedObj = Object.assign({}, received); const expectedObj = Object.assign({}, expected); // 对比所有键是否一致 const receivedKeys = Object.keys(receivedObj); const expectedKeys = Object.keys(expectedObj); const hasSameKeys = receivedKeys.length === expectedKeys.length && expectedKeys.every(key => receivedKeys.includes(key)); if (!hasSameKeys) { return { pass: false, message: () => `Expected keys: ${expectedKeys.join(', ')}, Received keys: ${receivedKeys.join(', ')}` }; } // 对比每个属性值 const pass = Object.keys(expectedObj).every(key => expect(receivedObj[key]).toEqual(expectedObj[key]) ); return { pass, message: () => pass ? 'Expected not to match exact properties' : `Properties do not match: ${JSON.stringify(receivedObj)} vs ${JSON.stringify(expectedObj)}` }; } });
然后在测试中使用:
test('myTest', () => { expect(new OurConstructor(255)).toMatchExactProperties({ a: true, b: true, c: true, }); });
这个方案复用性强,完全符合你“精确匹配所有属性”的需求,且不会触发任何Jest规则警告。
2. 将类实例转换为纯字面量对象
如果你的类实例没有不可序列化的属性(比如函数、Symbol、循环引用),可以直接将实例转为纯对象后用toStrictEqual匹配:
test('myTest', () => { const instance = new OurConstructor(255); // 转换为纯字面量对象 const plainObj = JSON.parse(JSON.stringify(instance)); expect(plainObj).toStrictEqual({ a: true, b: true, c: true, }); });
如果实例包含不可序列化的内容,可自定义递归转换函数:
function toPlainObject(obj) { if (typeof obj !== 'object' || obj === null) return obj; return Object.keys(obj).reduce((acc, key) => { acc[key] = toPlainObject(obj[key]); return acc; }, {}); }
然后在测试中用这个函数转换实例即可。
3. 局部禁用prefer-strict-equality警告
如果你只想快速解决当前测试的警告问题,可以在toEqual所在行添加ESLint注释,局部禁用规则:
test('myTest', () => { expect(new OurConstructor(255)).toEqual({ // eslint-disable-next-line jest/prefer-strict-equality a: true, b: true, c: true, }); });
这个方案最简单,但属于临时解决方案,不推荐长期大量使用,因为会失去Jest规则带来的严格性校验。
内容的提问来源于stack exchange,提问作者user19024399
相关产品推荐
相关产品推荐

