如何在Karate框架REST请求中正确使用JavaScript生成Payload?
关于Karate Framework中动态生成请求体的问题
问题场景
正常运行的代码示例
直接在Feature文件中定义请求体模板,变量能被正确解析,测试通过:
* def arrival = "22/10/2022" * def duration = "10" * def payload = """ { "bb:foo": { "@Start": "#(arrival)", "@Duration": "#(duration)" } } """
失败的代码示例
尝试通过外部JavaScript函数生成请求体时,测试失败。无论让JS返回字符串还是对象,都无法正确解析变量:
@-foo Feature: Foo Background: * def generatePayload = read('../../generatePayload.js') * def payloadRS = generatePayload(1) @-barr Scenario: barr * print('payloadRS : ' + payloadRS) * def payload = """ "#(payloadRS)" """ Given url endpoint_ws And path '/rest/services/myservice' And request payload And header Content-Type = "application/json" When method post Then status 200
初步尝试与转义问题
用户尝试通过JS返回对象生成请求体,但遇到斜杠转义问题:请求体中出现{"@Start":"12\/10\/2022"},而预期是{"@Start":"12/10/2022"}。JS代码如下:
function generatePayload(num) { return { "bb:foo": { "@Start": karate.get('arrival'), "@Duration": karate.get('duration') } } }
正确解决方案
方案1:直接使用JS返回的对象
Karate支持直接将JavaScript返回的对象作为请求体,无需用字符串模板包裹。修改Scenario中的代码,直接赋值对象即可,Karate会自动正确序列化为JSON,不会额外转义斜杠:
@-barr Scenario: barr * print('payloadRS : ' + payloadRS) * def payload = payloadRS // 直接使用JS返回的对象 Given url endpoint_ws And path '/rest/services/myservice' And request payload And header Content-Type = "application/json" When method post Then status 200
方案2:优化JS函数参数传递
为了让代码更清晰解耦,建议将Feature中的变量作为参数传递给JS函数,避免在JS中直接调用karate.get():
修改Feature的Background部分:
Background: * def arrival = "22/10/2022" * def duration = "10" * def generatePayload = read('../../generatePayload.js') * def payloadRS = generatePayload(arrival, duration)
修改JavaScript函数:
function generatePayload(arrival, duration) { return { "bb:foo": { "@Start": arrival, "@Duration": duration } } }
方案3:若需使用字符串模板(不推荐)
如果一定要通过字符串模板生成请求体,可使用Karate内置的karate.json()方法将对象转换为正确的JSON字符串,避免转义问题:
* def payload = karate.json(payloadRS)
内容的提问来源于stack exchange,提问作者Stéphane GRILLON
相关产品推荐
相关产品推荐

