Karate JSON对象不满足instanceof Object判断,如何解决?
Karate JSON对象类型与兼容类型检查方案
问题背景
现有基于JavaScript的应用通过以下代码检查JSON载荷类型,运行正常:
if(obj instanceof Object) { // handle JSON payload } else { throw new Error("no JSON payload"); }
但使用Karate测试时,该类型检查失败。推测Karate Feature中定义的JSON/对象属于不同类型,且无法修改应用代码适配Karate,需明确Karate JSON对象的类型,并找到兼容的类型检查方法。
Karate JSON对象的类型表现
从类型匹配错误信息可直接看出,Karate定义的JSON对象类型为MAP:
测试示例
Feature: Mismatch Scenario: MAP type * def o = {foo:"bar"} * match o == true
错误结果
match failed: EQUALS $ | data types don't match (MAP:BOOLEAN) {"foo":"bar"} true
类型检查差异验证
通过测试对比GraalVM纯JS环境与Karate环境的类型判断结果,差异明显:
测试代码
Feature: Code Background: * def instanceOf = obj => obj instanceof Object Scenario: Run pure ES6 JavaScript code in GraalVM * eval """ const pureInstanceOf = obj => obj instanceof Object; inLineObj = {foo:{bar:"baz"}}; karate.log(`pure inLineObj: ${pureInstanceOf(inLineObj)}`); // true karate.log(`inLineObj: ${instanceOf(inLineObj)}`); // false multiLineJson = { "foo": { "bar": "baz" } }; karate.log(`pure multiLineJson: ${pureInstanceOf(multiLineJson)}`); // true karate.log(`multiLineJson: ${instanceOf(multiLineJson)}`); // false """ Scenario: Karate JSON type * def inLineObj = {foo:{bar:"baz"}} * def test = instanceOf(inLineObj) * match test == true * def multiLineJson = """ { "foo": { "bar": "baz" } } """ * def test = instanceOf(multiLineJson) * match test == true
运行结果
15:53:59.945 [main] INFO com.intuit.karate - =================================================================== 15:53:59.984 [main] INFO com.intuit.karate - pure inLineObj: true 15:53:59.993 [main] INFO com.intuit.karate - inLineObj: false 15:53:59.994 [main] INFO com.intuit.karate - pure multiLineJson: true 15:53:59.995 [main] INFO com.intuit.karate - multiLineJson: false 15:54:00.001 [main] INFO com.intuit.karate - =================================================================== 15:54:00.050 [main] ERROR com.intuit.karate - code.feature:27 * match test == true match failed: EQUALS $ | not equal (BOOLEAN:BOOLEAN) false true code.feature:27 --------------------------------------------------------- feature: code.feature scenarios: 2 | passed: 1 | failed: 1 | time: 0,0653 ---------------------------------------------------------
纯GraalVM JS环境中obj instanceof Object返回true,但Karate中定义的对象返回false,两者行为不一致。
兼容的类型检查方案
Karate的JSON对象本质是Java的Map实现,而非原生JS对象,因此需要调整类型检查逻辑,同时兼容原生JS对象和Karate的MAP类型:
方案1:结合typeof与toString判断
function isJsonPayload(obj) { // 匹配原生JS对象或Karate的JavaMap类型 return typeof obj === 'object' && obj !== null && (obj instanceof Object || Object.prototype.toString.call(obj) === '[object JavaMap]'); }
方案2:利用Karate内置工具函数
Karate提供了karate.typeOf()方法,可直接判断对象类型:
function isJsonPayload(obj) { const type = karate.typeOf(obj); return type === 'object' || type === 'map'; }
方案3:检查对象特征
通过检查是否具备键值对操作特征来判断,同时可按需排除数组:
function isJsonPayload(obj) { if (obj == null || typeof obj !== 'object') return false; // 若需区分JSON对象和数组,可保留以下判断 if (Array.isArray(obj)) return false; // 匹配原生JS对象或具备get方法的Karate Map return obj instanceof Object || typeof obj.get === 'function'; }
这些方案无需修改原有应用的核心逻辑,只需在测试环境或类型检查层做兼容处理,即可让Karate测试通过类型校验。
内容的提问来源于stack exchange,提问作者droptix
相关产品推荐
相关产品推荐

