Karate框架中标记+自引用校验JSON时空值校验失效问题
Karate框架空值校验未生效的原因及解决方案
错误原因
你写的'##string? _ !==null'存在语法误解:Karate中##string?的?是nullable修饰符,表示允许字段为字符串或null,后面的_ !==null并未被当作自定义条件执行,相当于直接使用了##string?,所以null值被判定为匹配,导致测试意外通过。
另外你的测试中,aTest缺少street字段,但match aTest == eTest却通过,大概率是误将严格匹配写成了包含匹配(match contains),或者street字段的预期规则实际是可选(如写成##string?)。
正确写法
根据需求“name字段可选,若存在则必须是非null的字符串”,分两种场景调整:
场景1:name字段可选(允许不存在)
使用#?自定义断言结合可选字段标记,搭配match contains进行包含匹配:
* def aTest = """ { name: null, type: "House" } """ * def eTest = """ { name: '#? _ == null || (typeof _ === "string" && _ !== null)', type: '##string', street: '##string?' } """ * match aTest contains eTest
name: '#? ...':校验字段要么不存在/为null,要么是 non-null 的字符串street: '##string?':标记street为可选字段,允许不存在或为字符串match contains:只校验实际对象包含预期的字段规则,忽略额外字段或缺失的可选字段
场景2:name字段必须存在(但不能为null)
直接用自定义断言校验类型+非null,搭配match ==严格匹配:
* def aTest = """ { name: null, type: "House", street: "Main St" } """ * def eTest = """ { name: '#? typeof _ === "string" && _ !== null', type: '##string', street: '##string' } """ * match aTest == eTest
此时name为null会触发匹配失败,符合预期。
简化写法(使用Karate内置函数)
也可以用karate.typeOf()函数替代typeof,写法更统一:
name: '#(karate.typeOf(_) == "string" && _ != null)'
内容的提问来源于stack exchange,提问作者sp13aut
相关产品推荐
相关产品推荐

