如何用chai-things断言数组内所有对象不含多个指定属性
使用chai-things实现数组全量对象属性校验
核心问题根源
你之前使用的something修饰符,是chai-things提供的“存在匹配”语义的匹配器,它的校验逻辑是:只要数组中存在至少1个元素满足指定条件,断言就会通过,完全不关心其余元素的合规性。
比如你给出的示例数组中,第三个对象{name: "Johny Doe"}本身就不带email、phone键,所以原来的写法实际上会直接通过测试,哪怕前两个对象明确携带了违规的键,测试也会判为通过,根本达不到全量校验的目的。
正确实现方式
chai-things提供了和something语义完全对应的全量匹配修饰符all,用来遍历数组中的每一个元素,要求所有元素都必须满足指定条件才算断言通过。
场景1:要求所有对象都不能出现email、phone任意一个键
这是你当前场景的核心需求,直接将原写法中的something替换为all即可:
expect(myArray).to.all.not.include.any.keys("email", "phone")
逻辑说明:
not.include.any.keys("email", "phone")对单个对象的校验规则是——对象既不包含phone键;搭配all修饰符后,该规则会作用到数组的每一个元素上,只要有任意一个元素携带了两个键中的任意一个,断言就会抛出带元素位置的可定位错误。
场景2:要求所有对象不能同时包含email、phone两个键(允许单独存在其中一个)
这种场景不能直接使用内置的any.keys匹配器,需要通过satisfy自定义校验逻辑实现:
expect(myArray).to.all.satisfy((item) => { const hasEmail = Object.prototype.hasOwnProperty.call(item, 'email') const hasPhone = Object.prototype.hasOwnProperty.call(item, 'phone') // 规则:两个键不能同时存在 return !(hasEmail && hasPhone) })
常见踩坑提示
- 注意
any.keys的语义:include.any.keys(a, b)代表“包含a或者b任意一个键”,不要和“包含a且包含b”的全匹配逻辑混淆。 - 内置的
include.keys只会检查对象的可枚举属性,如果需要校验不可枚举属性、原型链上的属性,需要自行封装基于Object.hasOwnProperty的校验逻辑,避免误判。
内容的提问来源于stack exchange,提问作者ImInYourCode
相关产品推荐
相关产品推荐

