问题
In a Karate test - we are able to replace embedded expression for single key in a json. but when trying to replace in complex key of the json it is not working
input json:
{
"integration": {
"serviceData": {
"integrationService": {
"name": "#(integrationName)",
"description": "#(tenantID)",
"serviceData": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n <block type=\"start_block\" id=\"foOIiCF5aZGnie1GzBDB\" deletable=\"false\" x=\"150\" y=\"25\">\n <field name=\"ORCH_NAME\">Add2NumDocInputs</field>\n <field name=\"SVC_SIGNATURE\">{\"sig_in\":{\"rec_ref\":\"fld_[#(tenantID)]_stage00.documenttypes:sum2\",\"field_type\":\"recref\",\"node_type\":\"record\",\"field_dim\":\"0\"},\"sig_out\":{\"field_type\":\"record\",\"node_type\":\"record\",\"field_dim\":\"0\"}}</field>\n <field name=\"AUDIT_SETTINGS\"></field>\n <statement name=\"ADD_BLOCKS\">\n <block type=\"service_block_math\" id=\"aUqb0MAozTHQFuHj5rma\">\n <field name=\"SERVICE\">pub.math:addInts</field>\n <field name=\"SERVICE_DESC_FIELD\"></field>\n <field name=\"SERVICE_DETAILS\">{\"service\":\"pub.math:addInts\",\"map\":[{\"sourcePath\":\"/n2;1;0\",\"targetPath\":\"/num2;1;0\"},{\"sourcePath\":\"/n1;1;0\",\"targetPath\":\"/num1;1;0\"}]}</field>\n </block>\n </statement>\n </block>\n</xml>"
}
}
}
}
In the above json 'tenantID' is the key passed from the test case. 'tenantID' is replaced properly for 'description' key in the json. But it is not replaced for 'serviceData' key
Please suggest some solution. Thanks in advance
回答1:
EDIT: after posting the very long answer (see the end / second part of this answer), I realized there is a super-simple solution for you using the replace syntax of Karate:
* def integrationName = 'hello'
* def tenantID = 'world'
* def json =
"""
{
"integration": {
"serviceData": {
"integrationService": {
"name": "#(integrationName)",
"description": "#(tenantID)",
"serviceData": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n <block type=\"start_block\" id=\"foOIiCF5aZGnie1GzBDB\" deletable=\"false\" x=\"150\" y=\"25\">\n <field name=\"ORCH_NAME\">Add2NumDocInputs</field>\n <field name=\"SVC_SIGNATURE\">{\"sig_in\":{\"rec_ref\":\"fld_[<tenantID>]_stage00.documenttypes:sum2\",\"field_type\":\"recref\",\"node_type\":\"record\",\"field_dim\":\"0\"},\"sig_out\":{\"field_type\":\"record\",\"node_type\":\"record\",\"field_dim\":\"0\"}}</field>\n <field name=\"AUDIT_SETTINGS\"></field>\n <statement name=\"ADD_BLOCKS\">\n <block type=\"service_block_math\" id=\"aUqb0MAozTHQFuHj5rma\">\n <field name=\"SERVICE\">pub.math:addInts</field>\n <field name=\"SERVICE_DESC_FIELD\"></field>\n <field name=\"SERVICE_DETAILS\">{\"service\":\"pub.math:addInts\",\"map\":[{\"sourcePath\":\"/n2;1;0\",\"targetPath\":\"/num2;1;0\"},{\"sourcePath\":\"/n1;1;0\",\"targetPath\":\"/num1;1;0\"}]}</field>\n </block>\n </statement>\n </block>\n</xml>"
}
}
}
}
"""
* replace json.tenantID = tenantID
* match json ==
"""
{
"integration": {
"serviceData": {
"integrationService": {
"name": "hello",
"description": "world",
"serviceData": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n <block type=\"start_block\" id=\"foOIiCF5aZGnie1GzBDB\" deletable=\"false\" x=\"150\" y=\"25\">\n <field name=\"ORCH_NAME\">Add2NumDocInputs</field>\n <field name=\"SVC_SIGNATURE\">{\"sig_in\":{\"rec_ref\":\"fld_[world]_stage00.documenttypes:sum2\",\"field_type\":\"recref\",\"node_type\":\"record\",\"field_dim\":\"0\"},\"sig_out\":{\"field_type\":\"record\",\"node_type\":\"record\",\"field_dim\":\"0\"}}</field>\n <field name=\"AUDIT_SETTINGS\"></field>\n <statement name=\"ADD_BLOCKS\">\n <block type=\"service_block_math\" id=\"aUqb0MAozTHQFuHj5rma\">\n <field name=\"SERVICE\">pub.math:addInts</field>\n <field name=\"SERVICE_DESC_FIELD\"></field>\n <field name=\"SERVICE_DETAILS\">{\"service\":\"pub.math:addInts\",\"map\":[{\"sourcePath\":\"/n2;1;0\",\"targetPath\":\"/num2;1;0\"},{\"sourcePath\":\"/n1;1;0\",\"targetPath\":\"/num1;1;0\"}]}</field>\n </block>\n </statement>\n </block>\n</xml>"
}
}
}
}
"""
EDIT: this was the original answer (below), left here since it may be useful as a reference.
Wow may I say that is such a horrible combination of XML and JSON. Embedded expressions have a rule, they have to be strings that start with #(
So you need to split your flow into something like this. It is complex because of your payload. Not because of Karate :)
* def integrationName = 'hello'
* def tenantID = 'world'
* def recRef = 'fld_[' + tenantID + ']_stage00.documenttypes:sum2'
# by the way this is also possible as an embedded expression #('fld_[' + tenantID + ']_stage00.documenttypes:sum2')
* string signature = {"sig_in":{"rec_ref":"#(recRef)","field_type":"recref","node_type":"record","field_dim":"0"},"sig_out":{"field_type":"record","node_type":"record","field_dim":"0"}}
* def xml =
"""
<xml xmlns="http://www.w3.org/1999/xhtml">
<block type="start_block" id="foOIiCF5aZGnie1GzBDB" deletable="false" x="150" y="25">
<field name="ORCH_NAME">Add2NumDocInputs</field>
<field name="SVC_SIGNATURE">#(signature)</field>
<field name="AUDIT_SETTINGS"></field>
<statement name="ADD_BLOCKS">
<block type="service_block_math" id="aUqb0MAozTHQFuHj5rma">
<field name="SERVICE">pub.math:addInts</field>
<field name="SERVICE_DESC_FIELD"></field>
<field name="SERVICE_DETAILS">{"service":"pub.math:addInts","map":[{"sourcePath":"/n2;1;0","targetPath":"/num2;1;0"},{"sourcePath":"/n1;1;0","targetPath":"/num1;1;0"}]}</field>
</block>
</statement>
</block>
</xml>
"""
* xmlstring xml = xml
* def json =
"""
{
"integration": {
"serviceData": {
"integrationService": {
"name": "#(integrationName)",
"description": "#(tenantID)",
"serviceData": "#(xml)"
}
}
}
}
"""
* match json ==
"""
{
"integration": {
"serviceData": {
"integrationService": {
"name": "hello",
"description": "world",
"serviceData": "#string"
}
}
}
}
"""
* match json.integration.serviceData.integrationService.serviceData contains '"rec_ref":"fld_[world]_stage00.documenttypes:sum2"'
Please also read the doc on type conversion: https://github.com/intuit/karate#type-conversion
来源:https://stackoverflow.com/questions/50368391/embedded-expression-not-replaced-properly-in-the-complex-json