如何在Jest中测试包含自定义类实例的复杂嵌套树结构?
解决方案
Jest 原生支持和 Jasmine 逻辑一致的自定义相等测试器能力,你示例中的 API 实际是存在的,仅名称有微小差异:
- 直接使用
expect.addEqualityTesters注册全局相等判断规则即可,写法和你示例的逻辑几乎完全一致,该规则会自动递归作用于所有嵌套结构中的对象,适配你提到的动态 schema 场景:
class Person { constructor(name, age) { this.name = name; this.age = age; } } // Jest 原生API,直接注册自定义相等逻辑 expect.addEqualityTesters([ (first, second) => { if (first instanceof Person && second instanceof Person) { // 仅比较name字段,age差异忽略 return first.name === second.name; } // 非Person实例的场景返回undefined,自动走Jest默认相等判断逻辑 return undefined; } ]); // 原断言不需要任何修改,直接使用即可 expect(got).toEqual([ new Person('Alice', 10), new Person('Bob', 20), new Foo(a, b, c), [ new Person('Emma', 5), [x, y, z], new Person('Troy', 25), ], ]);
如果需要全局生效,把注册逻辑放到 Jest 配置的 setupFilesAfterEnv 对应的入口文件中即可;如果仅单测试文件需要,直接写在当前测试文件顶部即可。
- 如果你不想修改全局相等判断逻辑,也可以用不对称匹配器实现,无需注册全局规则:
// 封装Person匹配工具 const matchPerson = (expectedName) => expect.objectContaining({ name: expectedName }); // 断言时替换对应位置的Person实例 expect(got).toEqual([ matchPerson('Alice'), matchPerson('Bob'), new Foo(a, b, c), [ matchPerson('Emma'), [x, y, z], matchPerson('Troy'), ], ]);
这种方案更灵活,不会影响其他测试用例的断言逻辑。
你提到的旧 issue 是早期 Jest 尚未移植该 Jasmine 特性时提出的,后续版本已经实现了对应能力,只是文档提及较少,并非该需求不合理或者没有解决方案。
内容的提问来源于stack exchange,提问作者Decade Moon
相关产品推荐
相关产品推荐

