You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Karate 1.3.0起JavaScript函数处理JSON对象异常问题咨询

Karate 1.3.0+ 中JavaScript函数处理JSON对象的异常及解决办法

问题背景

在Karate 1.2.0及更早版本中,Feature文件中可通过如下JavaScript函数处理JSON对象(注:原代码存在笔误,函数内部错误引用全局变量myObj,以下示例已修正为使用参数obj):

* def checkObj =
"""
    function(obj) {
        const keys = Object.keys(obj);
        print("### object:", JSON.stringify(obj));
        print("### keys:", keys);
        keys.forEach(key => {
            print("### key:", key);
            print("### value:", obj[key]);
        });
    }
""" 
* def myObj = { foo: "bar" }
* checkObj(myObj)

预期输出(Karate 1.2.0及更早)

### object: {"foo":"bar"}
### keys: foo
### key: foo
### value: bar

实际输出(Karate 1.3.0+)

从Karate 1.3.0开始,执行相同代码会输出Java Map的内置方法而非对象的业务键值:

### object: {}
### keys: get,values,clear,replaceAll,entrySet,forEach,containsValue,keySet,getOrDefault,remove,put,clone,isEmpty,replace,size,merge,putAll,putIfAbsent,compute,containsKey,computeIfAbsent,computeIfPresent,equals,toString,hashCode
### key: get
### value: undefined
### key: values
### value: undefined
... // 剩余方法输出省略

但内联JavaScript代码仍可正常工作:

* def myObj = { foo: "bar" }
* print("### object:", JSON.stringify(myObj))
* print("### key(s):", Object.keys(myObj))
* print("### value:", myObj.foo)

输出符合预期:

### object: {"foo":"bar"}
### key(s): foo
### value: bar

原因分析

Karate 1.3.0对JavaScript引擎的对象传递逻辑做了未文档化的变更:传递给独立JS函数的JSON对象不再自动转换为原生JavaScript对象,而是保留为Java HashMap的包装实例。因此Object.keys()会遍历Java Map的内置方法,而非业务键值;而内联JS代码因执行上下文不同,仍会自动完成对象转换。

解决办法

方法1:将Java Map转换为原生JS对象

在函数内部通过JSON.parse(JSON.stringify(obj))把传入的对象转成原生JS对象后再处理:

* def checkObj =
"""
    function(obj) {
        const nativeObj = JSON.parse(JSON.stringify(obj));
        const keys = Object.keys(nativeObj);
        print("### object:", JSON.stringify(nativeObj));
        print("### keys:", keys);
        keys.forEach(key => {
            print("### key:", key);
            print("### value:", nativeObj[key]);
        });
    }
""" 
* def myObj = { foo: "bar" }
* checkObj(myObj)

方法2:使用Karate内置API获取键值

Karate提供原生karate.keys()方法直接获取对象的键列表,无需依赖JS的Object.keys():

* def checkObj =
"""
    function(obj) {
        const keys = karate.keys(obj);
        print("### object:", JSON.stringify(obj));
        print("### keys:", keys);
        keys.forEach(key => {
            print("### key:", key);
            print("### value:", obj[key]);
        });
    }
""" 
* def myObj = { foo: "bar" }
* checkObj(myObj)

方法3:直接调用Java Map的方法

如果不需要转换为原生JS对象,可直接调用Java Map的keySet()方法获取键,在JS中转换为数组后处理:

* def checkObj =
"""
    function(obj) {
        const keys = Array.from(obj.keySet());
        print("### object:", JSON.stringify(obj));
        print("### keys:", keys);
        keys.forEach(key => {
            print("### key:", key);
            print("### value:", obj.get(key));
        });
    }
""" 
* def myObj = { foo: "bar" }
* checkObj(myObj)

内容的提问来源于stack exchange,提问作者Drunda Nibel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:01:10