Karate v1.1.0中JSON可选键缺失时触发Schema校验报错问题
问题根因
Karate 1.0及之后版本确实调整了Schema校验的语法规则,该报错是版本行为变更导致,并非代码逻辑写错。
0.9.6版本中,##(schema变量)的语法默认同时包含两层语义:
- 标记当前字段为可选,字段不存在/为null时直接通过校验
- 字段存在时,按照括号内引用的Schema执行结构校验
1.0版本后这个语法的语义被拆分收敛:括号内的表达式仅会在字段存在时触发校验,不再自动承担「标记字段可选」的作用,因此会触发actual does not contain key - 'store'报错。
修复方案
可任选以下一种写法调整Schema定义,两种都能在v1.1.0版本正常运行:
方案1:使用1.0版本新增的类型+Schema引用语法(最简洁)
直接修改depts_schema的定义,用##object显式标记store是可选对象字段,后接引用的Schema即可:
* def store_schema = {"code":'#string',"usable":'#boolean'} * def depts_schema = {"id":'#number',"store":'##object store_schema'}
这个写法的语义和0.9.6版本的预期完全一致:store字段可以不存在,存在时必须是对象,且符合store_schema定义的结构。
方案2:使用条件校验表达式兼容旧逻辑
如果需要兼容更复杂的判断逻辑,可以用##?开头的条件匹配语法,显式声明可选逻辑:
* def store_schema = {"code":'#string',"usable":'#boolean'} * def depts_schema = {"id":'#number',"store":'##? !_ || karate.match(_, store_schema).pass'}
这段逻辑的含义是:如果store字段不存在/值为null则直接通过,否则执行store_schema的结构校验。
修正后可直接运行的完整代码
* def response = """ { "depts": [ { "id": 192, "store": { "code": "1004", "usable": true } }, { "id": 201, "store": { "code": "983", "usable": false } }, { "id": 203 } ] } """ * def store_schema = {"code":'#string',"usable":'#boolean'} * def depts_schema = {"id":'#number',"store":'##object store_schema'} * match response == """ { "depts": '##[] depts_schema' } """
运行后不会再报缺失store键的错误。
注:这个变更在Karate 1.0的升级说明中归类为「语法语义收敛」,主要是为了消除旧版本中
##()语法同时承担可选标记、存在时校验两个职责带来的歧义问题,大量从0.9.x升级的用户都遇到过同类问题。
内容的提问来源于stack exchange,提问作者SACHIN SHANBAG
相关产品推荐
相关产品推荐

