I'm using REST-Assured for testing some RESTful webservices. Here's my JSON:
{
"status":true,
"responseData":{
"orderLevelReasons":[
{
"reasons":[
{
"reasonId":"129cfea8-b022-4dc8-9811-222a324f46aa",
"reasonName":"COD Amount Mismatch"
},
{
"reasonId":"a881fd5c-626e-438c-8026-646aa2a19098",
"reasonName":"Gave wrong information"
},
{
"reasonId":"543d438a-88cc-487c-86e4-19eecefa9ca7",
"reasonName":"Late delivery"
},
{
"reasonId":"080cd7c1-7a37-48ad-9090-57286d93ea41",
"reasonName":"Parcel not received"
},
{
"reasonId":"5ca3d9b4-0fa2-49da-a534-a6f2e7eccc07",
"reasonName":"Staff did not inform about the parcel arrival"
}
],
"issueName":"ISSUE TYPE 1",
"issueId":"0c2c37a6-62b6-4c28-ab6c-566487d045bd",
"hint":""
},
{
"reasons":[
{
"reasonId":"129cfea8-b022-4dc8-9811-222a324f46aa",
"reasonName":"COD Amount Mismatch"
},
{
"reasonId":"14975b5d-23fb-4735-8082-2e02d6335788",
"reasonName":"Data issue"
},
{
"reasonId":"7e6e8446-3774-4589-9171-8e7ab0a7f73b",
"reasonName":"Delivery BOY did not inform before delivering"
},
{
"reasonId":"543d438a-88cc-487c-86e4-19eecefa9ca7",
"reasonName":"Late delivery"
},
{
"reasonId":"080cd7c1-7a37-48ad-9090-57286d93ea41",
"reasonName":"Parcel not received"
},
{
"reasonId":"8e430c71-f28b-49e4-9946-e0bd5131768b",
"reasonName":"Refuse to come doorstep"
},
{
"reasonId":"515d0fa4-a44c-47eb-a7a2-5ddae778f37a",
"reasonName":"Extra Amount taken By Partner Staff"
}
],
"issueName":"ISSUE TYPE 2",
"issueId":"ac902377-3db2-462a-8e53-48b06d1aff1f",
"hint":""
}
],
"productLevelReasons":[
{
"reasons":[
{
"reasonId":"6129dcb8-1ae5-4d7d-9c95-4c0ec2f69ded",
"reasonName":"Some reason1"
},
{
"reasonId":"febec32b-b243-4509-b46a-20d9f4747ca3",
"reasonName":"Some reason2"
},
{
"reasonId":"d8a492b8-f816-41e6-b45d-5ec29f3a0785",
"reasonName":"Some reason3"
},
{
"reasonId":"c0c98489-6401-455a-9145-f52664d8aff4",
"reasonName":"Some reason4"
},
{
"reasonId":"ef2b4147-ee76-4961-b784-63e848a84167",
"reasonName":"Some reason5"
},
{
"reasonId":"7f4f9657-17b2-407b-aed7-16b221bf3229",
"reasonName":"Some reason6"
},
{
"reasonId":"2aa83be6-60cb-43dc-9273-c41e6047315e",
"reasonName":"Others"
},
{
"reasonId":"c432f563-f835-4710-8055-5ee9e0fe1409",
"reasonName":"Some reason7"
}
],
"orderItemName":"Item1",
"orderItemId":961253,
"hint":""
}
]
},
"message":"OK"
}
I would like to fetch:
reasonId
values under
responseData.orderLevelReasons
.reasonId
values
under responseData.productLevelReasons
where orderItemId
is
961253
(as there could be productLevelReasons for multiple orderItemIds
).I Googled for this quite a lot and found that this can be achieved using JsonPath
, but I could not figure out what exactly would be the JsonPath expressions for each of my purposes.
We can transform the response to Java list in Rest Assured. This can be achieved when we have a JSON array Response. To convert the JSON array to List, we need to use the method as. (List.
JsonPath is an alternative to using XPath for easily getting values from a Object document. It follows the Groovy dot notation syntax when getting an object from the document. You can regard it as an alternative to XPath for XML.
We can iterate through and access the JSON array elements using Rest Assured. First, we shall obtain a Response body which is in JSON format from a request. Then convert it to string. To obtain JSON array size, we have to use the size method on the JSON array.
: operator is the array slice operator, so you can slice collections using the syntax [start:end:step] to return a subcollection of a collection. ( ) operator lets you pass a script expression in the underlying implementation's script language. It's not supported by every implementation of JSONPath, however. ?
A list of all reasonId values under responseData.orderLevelReasons
$.responseData.orderLevelReasons[*].reasons[*].reasonId
The [*] for orderLevelReasons is necessary if you want the reasons from all items in the orderLevelReasons collection. If not you can replace it with [0] and you can get a distinct list (assuming the same reasons repeat for each orderLevelReasons).
A list of all reasonId values under responseData.productLevelReasons where orderItemId is 961253 (as there could be productLevelReasons for multiple orderItemIds).
$.responseData.productLevelReasons[?(@.orderItemId=='961253')].reasons[*].reasonId
This is also not distinct. You'll need to de-duplicate if duplicate reasons can exist.
I validated both of your JsonPath expressions at jsonpath.curiousconcept.com, both of them are valid. But the Java code gives error for some reason.
I have looked into this. The rest-assured framework does not actually implement JsonPath, but a proprietary path based query syntax for JSON. Unhappily the name is the same but it is actually based on a completely different standard.
This docs page explains:
Note that the JsonPath implementation uses Groovy's GPath syntax and is not to be confused with Jayway's JsonPath implementation.
The JsonPath tag on StackOverflow is concerned with the accepted JsonPath specification, and not the rest-assured specification.
Based on my research I would conclude that the rest-assured jsonpath implementation does not support your requirement. You should use an implementation that does, such as Jayway's one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With