循环中调用Karate.call触发PolyglotException问题求助
问题描述
在Karate测试的JS函数循环中调用karate.call时,抛出Polyglot类型错误,提示找不到匹配的重载方法,导致执行失败。
测试场景代码
Scenario: Test * def userList = Java.type('aws.iamUtil.users.ListUsers') * json userID = userList.listAwsIamUserId() * def eSearch = read(pathConfig.featureDir.elasticSearchFeatures + 'ElasticSearch.feature@elasticSearch') * def fun = """ function(array) { var temp = ""; for (var i = 0; i < array.length; i++) { temp = { principalId: array[i] }; karate.call(eSearch); } return temp; } """ * def result = fun(userID)
执行报错信息
js执行失败:
01: fun(userID)
<<<<
org.graalvm.polyglot.PolyglotException: 类型错误:调用com.intuit.karate.core.ScenarioBridge@445dc8dc的call成员失败,原因:未找到匹配的重载方法(重载方法:[Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.call(boolean,java.lang.String)], Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.call(java.lang.String,org.graalvm.polyglot.Value)], Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.call(java.lang.String)], Method[public java.lang.Object com.intuit.karate.core.ScenarioBridge.call(boolean,java.lang.String,org.graalvm.polyglot.Value)]], 参数:[JavaObject[classpath:features/api/elastic_search/ElasticSearch.feature (com.intuit.karate.core.Feature)] (HostObject)])
.:anonymous(Unnamed:5)
问题原因
在JS函数内部调用karate.call时,无法直接传入通过read()获取的Feature对象。karate.call的重载方法仅支持接收字符串路径或字符串路径+参数对象的组合,传入Feature实例会触发类型匹配失败。
修正方案
方式1:直接传递Feature路径并传参
修改JS函数,使用Feature路径字符串调用karate.call,同时传递principalId参数:
Scenario: Test * def userList = Java.type('aws.iamUtil.users.ListUsers') * json userID = userList.listAwsIamUserId() * def eSearchPath = pathConfig.featureDir.elasticSearchFeatures + 'ElasticSearch.feature@elasticSearch' * def fun = """ function(array) { var results = []; for (var i = 0; i < array.length; i++) { var params = { principalId: array[i] }; var callResult = karate.call(eSearchPath, params); results.push(callResult); } return results; } """ * def result = fun(userID)
方式2:使用Karate内置循环替代JS函数
Karate本身支持karate.forEach内置循环,无需手写JS函数,更简洁且避免类型问题:
Scenario: Test * def userList = Java.type('aws.iamUtil.users.ListUsers') * json userID = userList.listAwsIamUserId() * def eSearch = read(pathConfig.featureDir.elasticSearchFeatures + 'ElasticSearch.feature@elasticSearch') * karate.forEach(userID, function(item){ karate.call(eSearch, { principalId: item }); })
内容的提问来源于stack exchange,提问作者Kanishk Jadhav

