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
相关产品推荐
相关产品推荐

