Jest如何测试数组不包含指定黑名单列表中的任意值
问题原因
expect.arrayContaining(matches) 的原生语义是校验被测数组是否包含matches数组的全部元素,因此添加.not修饰后,语义变为「被测数组不需要包含matches的所有元素即可通过校验」。你传入["3", "4"]时,被测数组仅包含"3"、缺少"4",没有满足「包含所有匹配项」的条件,因此.not修饰后测试通过,不符合你的预期。
解决方案
方案1:遍历校验(无额外配置、最常用)
直接遍历黑名单数组对每个元素做存在性校验,不用逐行手写重复断言:
const blackList = ["3", "4"]; const targetArr = ["1", "2", "3"]; blackList.forEach(item => expect(targetArr).not.toContain(item))
只要数组包含任意黑名单元素,对应遍历项的断言就会直接抛出失败。
方案2:单条断言实现
借助数组原生方法判断是否存在违禁项,写为单条断言:
const blackList = ["3", "4"]; const targetArr = ["1", "2", "3"]; // 校验不存在任意违禁项 expect(targetArr.some(item => blackList.includes(item))).toBe(false)
如果需要更清晰的失败提示,可以补充自定义错误信息:
const forbiddenItems = targetArr.filter(item => blackList.includes(item)) expect(forbiddenItems).toEqual([], `检测到数组包含黑名单元素:${forbiddenItems.join(',')}`)
方案3:自定义匹配器(高频使用场景)
如果项目中这类校验需求很多,可以全局注册自定义Jest匹配器一劳永逸:
// 放在jest配置的setup文件中全局注册 expect.extend({ toContainNoForbiddenItems(received, forbiddenList) { const matchedItems = received.filter(item => forbiddenList.includes(item)) if (matchedItems.length === 0) { return { pass: true, message: () => `预期数组不包含黑名单元素,实际无匹配违禁项` } } return { pass: false, message: () => `预期数组不包含黑名单元素,实际匹配到违禁项:${matchedItems.join(',')}` } } }) // 业务代码中直接调用 expect(["1", "2", "3"]).toContainNoForbiddenItems(["3", "4"])
内容的提问来源于stack exchange,提问作者Manuel Mauky
相关产品推荐
相关产品推荐

