Karate V1.3.x升级后JS函数JSON转Map致对象对比失败求助
解决Karate 1.3.x中JS函数接收Java Map而非JSON对象导致的对比失败问题
问题根源
Karate 1.3.0升级了GraalVM JavaScript引擎,调整了Java对象(如java.util.Map)的跨语言交互逻辑:此前版本会自动将Java Map转换为原生JavaScript对象,而1.3.x版本直接暴露Java Map实例给JS函数。这导致你的equalObjects函数中Object.keys()获取到的是Java Map的原生方法(如function () { [native code] }),而非目标对象的属性键,最终对比失败。
解决方案
方案1:改用Karate原生断言(推荐)
Karate本身内置了数组包含的深度对比能力,完全可以替代自定义JS函数,代码更简洁且适配版本变化:
* json provider = read('classpath:provider.json') Given path 'v1', 'ads' * retry until response.adUnits contains provider When method get Then status 200
如果需要更精确的嵌套对象严格对比,可使用karate.match:
* retry until karate.match(response.adUnits, '#contains ' + provider).pass
方案2:修改JS函数,自动转换Java对象为JS对象
在你的对比函数中添加转换逻辑,将Java Map/List转换为原生JS对象:
function equalObjects(obj1, obj2) { // 工具函数:递归转换Java集合为JS对象 const convertToJs = obj => { if (!obj) return obj; if (obj instanceof java.util.Map || obj instanceof java.util.List) { return JSON.parse(karate.toJson(obj)); } if (typeof obj === 'object') { Object.keys(obj).forEach(key => { obj[key] = convertToJs(obj[key]); }); } return obj; }; obj1 = convertToJs(obj1); obj2 = convertToJs(obj2); const objectKeys = Object.keys, typeOfObj1 = typeof obj1, typeOfObj2 = typeof obj2; return obj1 && obj2 && typeOfObj1 === 'object' && typeOfObj1 === typeOfObj2 ? ( objectKeys(obj1).length === objectKeys(obj2).length && objectKeys(obj1).every(key => equalObjects(obj1[key], obj2[key])) ) : (obj1 === obj2); }
方案3:在Feature文件中提前转换参数
在调用JS函数前,将Java Map手动转换为JS对象:
* json provider = read('classpath:provider.json') * def providerJs = JSON.parse(karate.toJson(provider)) Given path 'v1', 'ads' * retry until findObjectInArray(response.adUnits, providerJs) === true When method get Then status 200
内容的提问来源于stack exchange,提问作者eulerstoastient
相关产品推荐
相关产品推荐

