如何使用Jest匹配器匹配通配符对象键并仅断言值?
解决方案
要实现将foo的键视为通配符、仅断言值的结构,你可以通过以下两种方式实现:
方法一:使用Jest内置的toSatisfy匹配器(Jest 29+支持)
直接在断言中对foo对象的所有值进行遍历检查:
expect(value).toStrictEqual({ context: expect.objectContaining({ version: expect.any(Number), // 注意:原数据中version是Number类型,示例中的String是错误的 }), value: { foo: expect.toSatisfy(fooObj => { // 确保foo是一个非空对象 expect(fooObj).toBeInstanceOf(Object); expect(fooObj).not.toBeNull(); // 遍历所有值,断言每个值都是包含两个BigInt的数组 Object.values(fooObj).forEach(item => { expect(item).toHaveLength(2); expect(item[0]).toBeInstanceOf(BigInt); expect(item[1]).toBeInstanceOf(BigInt); }); return true; }) } });
方法二:自定义匹配器(兼容更多Jest版本)
如果你的Jest版本不支持toSatisfy,可以自定义一个匹配器来检查对象的所有值是否符合预期:
// 自定义匹配器:检查对象的所有值是否匹配指定断言 expect.extend({ toAllValuesMatch(received, assertFn) { const allMatch = Object.values(received).every(val => { try { assertFn(val); return true; } catch { return false; } }); if (allMatch) { return { message: () => `对象所有值均符合预期`, pass: true }; } else { return { message: () => `存在对象值不符合预期断言`, pass: false }; } } }); // 使用自定义匹配器进行断言 expect(value).toStrictEqual({ context: expect.objectContaining({ version: expect.any(Number), }), value: { foo: expect.toAllValuesMatch(item => { expect(item).toHaveLength(2); expect(item[0]).toBeInstanceOf(BigInt); expect(item[1]).toBeInstanceOf(BigInt); }) } });
关键说明
- 两种方法都忽略
foo的键名,仅关注值的结构 - 若不需要严格限制数组长度为2,可以移除
toHaveLength(2)的断言 - 原示例中
version: expect.any(String)不符合数据实际类型,已修正为Number
内容的提问来源于stack exchange,提问作者steveluscher
相关产品推荐
相关产品推荐

