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

Karate DSL读取独立JSON时embedded_json_msg类型不匹配(OTHER:MAP)

问题原因

PostgreSQL JDBC驱动查询json/jsonb类型列时,默认返回的是PGobject实例(部分驱动版本返回字符串),不是Karate匹配逻辑可直接识别的原生JSON结构(Map/List嵌套结构),因此直接做全量对象匹配时会触发类型不匹配。非JSON类型的列因为JDBC返回的是字符串、数字等基础类型,所以用#regex、#notnull等匹配符可以正常校验。

解决方法

方案1:改造DBUtils工具类(推荐,一劳永逸)

直接在db.readRow()方法内部完成JSON类型字段的转换,上层测试逻辑不需要额外处理类型差异,全量匹配可以直接正常运行:

  • 遍历ResultSet读取列数据时,判断当前列的类型名是否为json或jsonb
  • 对这类列,将返回的PGobject值解析为普通Map/List结构存入结果Map,不保留原PGobject类型

参考Java实现片段:

// 读取列值时的类型判断逻辑
if ("json".equals(columnTypeName) || "jsonb".equals(columnTypeName)) {
    PGobject pgObj = (PGobject) rs.getObject(columnIndex);
    // 用项目里已有的Jackson/Gson等JSON工具把字符串转成Map/List即可
    Object jsonValue = objectMapper.readValue(pgObj.getValue(), Object.class);
    rowMap.put(columnName, jsonValue);
} else {
    rowMap.put(columnName, rs.getObject(columnIndex));
}

改造完成后,原代码第15行的match dbResult == dbExpectedResults.karateJsonIssue.embedded_json_table就可以直接运行,不需要额外写单字段转换的临时逻辑,后续同一张表新增其他JSON类型列也可以自动兼容。

方案2:不修改Java代码,在feature层统一转换

如果暂时不能调整DBUtils的代码,可以在查询拿到dbResult之后,统一对JSON字段做类型转换,不需要单独拆出来做单字段匹配:

* def dbResult = db.readRow("select * from embedded_json_table")
// 将JSON类型字段转为Karate可识别的JSON结构
* set dbResult.embedded_json_message = dbResult.embedded_json_message.toString()
* json dbResult.embedded_json_message = dbResult.embedded_json_message
// 直接执行全量匹配
* match dbResult == dbExpectedResults.karateJsonIssue.embedded_json_table

如果表中有多个JSON类型列,写个简单的循环批量转换即可,不需要逐个字段硬编码处理。


内容的提问来源于stack exchange,提问作者Ed Mendonca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:45:49