You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 12:46:58