如何在Jest中匹配含嵌套对象数组的发送与返回数据?
解决嵌套对象数组匹配时忽略额外字段的问题
这个问题的核心在于 expect.arrayContaining 会严格匹配数组中的每个对象——如果返回的对象多了数据库自动生成的 id 这类额外字段,直接对比就会因为字段不匹配而报错。要解决这个问题,我们可以结合 expect.objectContaining 来忽略那些我们不关心的额外字段,只校验需要匹配的内容。
具体实现思路
expect.objectContaining 的特性是只检查你指定的键值对是否存在且匹配,完全忽略对象中的其他字段。我们可以把它和 expect.arrayContaining 嵌套使用,层层校验嵌套的数组和对象:
- 顶层对象用
expect.objectContaining忽略返回数据中的id,只校验我们发送的name和options。 - 对
options数组,用expect.arrayContaining包裹,数组内每个元素再用expect.objectContaining校验name和嵌套的variants,忽略option自身的id。 - 对
variants数组,同样用expect.arrayContaining+expect.objectContaining组合,只校验name,忽略variant的id。
代码示例
假设你的发送数据和返回数据如下:
// 发送的数据 const sentData = { "name": "red dress", "options": [ { "name": "size", "variants": [ { "name": "M" }, { "name": "L" }, { "name": "S" } ] } ] }; // 服务器返回的数据(多了id字段) const responseData = { "id": "dc67efd8-dcc4-43df-a8eb-9d95ea641749", "name": "red dress", "options": [ { "id": "option-123", "name": "size", "variants": [ { "id": "var-M", "name": "M" }, { "id": "var-L", "name": "L" }, { "id": "var-S", "name": "S" } ] } ] };
对应的断言写法:
expect(responseData).toEqual(expect.objectContaining({ // 匹配顶层的name name: sentData.name, // 匹配options数组 options: expect.arrayContaining( sentData.options.map(option => expect.objectContaining({ // 匹配option的name name: option.name, // 匹配variants数组 variants: expect.arrayContaining( option.variants.map(variant => // 匹配variant的name,忽略其他字段 expect.objectContaining(variant) ) ) }) ) ) }));
额外优化:校验数组长度
如果你需要确保返回的数组(比如options或variants)没有多出来的元素,可以在断言前先校验长度:
// 确保返回的options数量和发送的一致 expect(responseData.options.length).toBe(sentData.options.length); // 确保每个option的variants数量也一致 responseData.options.forEach((resOption, index) => { expect(resOption.variants.length).toBe(sentData.options[index].variants.length); });
这样既可以忽略无关的id字段,又能保证数组的元素数量符合预期,不会出现额外的选项或变体。
内容的提问来源于stack exchange,提问作者Khotey Vitaliy
相关产品推荐
相关产品推荐

