JMeter: Update Empty JSON hashmap groovy - json

Response from http request:
{"Preferredvalue":{"notations":[]}}
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
I am able to get up to notations and also the size.
If the size is 0, I want to update the notations as below
{"Preferredvalue":{"notations":[{"Name":${firstName},"lName":${lastName}}]}
firstName and lastName are Jmeter variable which are fetched from another calls, and I want to use these values in my another call and send a PUT request.
Searched a lot but couldnt find an answer :(
Best,

Something like:
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
def notations = response.Preferredvalue.notations
if (notations.size() == 0) {
notations.add([Name: vars.get('firstName'), lName: vars.get('lastName')])
}
def request = new groovy.json.JsonBuilder(response).toPrettyString()
vars.put('request', request)
should do the trick for you. Refer generated value as ${request} where required
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy: What Is Groovy Used For?

Related

How to extract the Substring from URL present in JSON response using JMeter

I've the below JSON response received from the HTTP request. I want to extract the parameters from the node "url" present in the JSON response.
{"Id":"7S9LyBqyv1e0trKrVuP1OOZGHeg","Url":"https://abcd.com:443/u/custom-response?prov=34545sdf-9013e2e61e66&realmeId=%2Fxxxx","realmeId":"/abcd"}
In the above JSON response, i want to retrieve the value of "prov" which is 34545sdf-9013e2e61e66 using JMeter.
Solution Tried: Used Beanshell to read the response.
String url = vars.get("successURL");
vars.put("responseURL",url.toString());
responseURL = responseURL.replaceAll(":"," ");
log.info("String URL "+responseURL.toString());
Error Message:
attempt to resolve method: toString() on undefined variable or class name: responseURL
I think you need to update this line:
responseURL = responseURL.replaceAll(":"," ");
to something like:
responseURL = vars.get("responseURL").replaceAll(":"," ");
However I don't guarantee that it will work because I don't know how do you get this successURL variable.
What will work is doing everything in one shot using JSR223 PostProcessor and Groovy language which has built-in JSON support, suggested code:
def url = new groovy.json.JsonSlurper().parse(prev.getResponseData()).Url
def params = org.apache.http.client.utils.URLEncodedUtils.parse(new URI(url), 'UTF-8')
params.each { param ->
log.info(param.getName() + '=' + param.getValue())
}
Demo:
More information: Apache Groovy - Why and How You Should Use It
You don't need to use complex Beanshell coding, You can do this easily using - Regular Expression Extractor.
Here the example:-
You can see required value extracted and stored in variable name give in Regular expression extractor:
To understand try out reg-ex, you can use https://regex101.com/

How to filter a complex response in karate dsl using jsonPath?

I am getting below response from a REST API, but I am finding it difficult to extract label value from the received response and assign it to a variable to use it later in script.
Here is the RESPONSE::
{
"result": "SUCCESS",
"rawAttr": "[{\"attributes\":[{\"name\":\"resourceid\",\"value\":\"7A7Q123456\"},{\"name\":\"physicalid\",\"value\":\"7A7Q123456\"},{\"name\":\"dsw:label\",\"value\":\"MY Product00004285\"},{\"name\":\"dsw:created\",\"value\":\"2019-11-06T08:39:39Z\"}]}]",
"physicalid": "7A7Q123456",
"contextPath": "/path",
"id": "7A7Q123456",
"message": null
}
I am able to get response.id and response.result which is helpful for validation but I am not able to get the dsw:label value which is MY Product00004285
When I do def Arr = response.rawAttr I get the below value whether it is Array or String I am confused. Seems like it is a string.
[{"attributes":[{"name":"resourceid","value":"7A7Q123456"},{"name":"physicalid","value":"7A7Q123456"},{"name":"dsw:label","value":"MY Product00004298"},{"name":"dsw:created","value":"2019-11-06T08:39:39Z"}]}]
It is very easy to extract the label in JMeter JSON Extractor using below JSON Path expression
$.attributes.value[2]
Refer Karate's type conversion capabilities: https://github.com/intuit/karate#type-conversion
So you can do this:
* json attr = response.rawAttr
And then you are all set.
Thanks to an example and documentation on converting string to json.
Got it how to do.
And def strVar = response.rawAttr
And json jsonVar = strVar
And def attrb = karate.jsonPath(jsonVar, '$..attributes.[2].value')[0]
And print '\n\n Attrb\n', attrb
Links I referred:
Json Path evaluator
Karate doc reference for type conversion
Karate example for type-conversion

How to get specific content from JSON response using context.expand?

I'm trying to use context.expand to get response and specific content from within the response,
def response = context.expand( '${Ranks of documents with SSE hits reflects scores#Response}' )
I also need to get specific detail from within the response, say if response has an array of ranks:
"ranks":[2234, 1234]
How can get both values of ranks?
You can use JsonSlurper from the groovy script testStep, supposing you get the follow JSON:
{"ranks":[2234, 1234]}
from your code:
def response = context.expand( '${Ranks of documents with SSE hits reflects scores#Response}')
You can use the JsonSlurper as follows to get your "ranks" values:
import groovy.json.JsonSlurper
// here I use this JSON as example, but you can
// parse directly your response which you get with context.expand
def response = '{"ranks":[2234, 1234]}'
def jsonRoot = new JsonSlurper().parseText(response)
log.info jsonRoot.ranks[0]
log.info jsonRoot.ranks[1]
Hope this helps,
Internally, SoapUI will convert almost anything to XML. You could grab just that node with ${step_name#ResponseAsXml}, and then parse it however you need to. Something like:
def ranksString = context.expand( '${Ranks of documents with SSE hits reflects scores#ResponseAsXml#//*:ranks}' )
def ranksArray = ranksString.split(",").trim()
log.info ranksArray[0]
log.info ranksArray[1]

Python Unittest for method returning json string

I ma new to writing python unit tests. I have a method in a class returning a Json response from an API. The JSON response contains attributes such as data, token, object name and status. The method hits API and returns response with different values each time, so I can't hard code a response and test it. How can I write a unit test for this type of method.
One thing, I thought of is to check whether the response is not null. Is there any other type of checks I can do here.
Each time it returns a different token, date(timestamp). The status will be same.
def Json_get_status(self):
get_url = "xxxx" #URL to hit API
r = requests.get(get_url)
self.get_json = json.loads(r.text)
self.get_token=self.get_json["token"]
self.get_date=self.get_json["date"]
self.get_status=self.get_json["status"]
return self.get_json
If your method under test is supposed to "read the status correctly", then you might want to specifically test that.
So assuming your app is something like
def read_status(response):
parsed = json.loads(response)
# does other stuff
return something
Then in your test_unit.py
def test_read_status(self):
mock_input_val = {'something': 'good val'}
expected_positive_return_val = something
self.assertEqual(read_status(json.dumps(mock_input_val)),
expected_positive_return_val)
Also good to do a negative test for the condition where read_status either fails to parse the json object or finds an error in the response.

How to get Slurpable data from REST client in Groovy?

I have code that looks like this:
def client = new groovyx.net.http.RESTClient('myRestFulURL')
def json = client.get(contentType: JSON)
net.sf.json.JSON jsonData = json.data as net.sf.json.JSON
def slurper = new JsonSlurper().parseText(jsonData)
However, it doesn't work! :( The code above gives an error in parseText because the json elements are not quoted. The overriding issue is that the "data" is coming back as a Map, not as real Json. Not shown, but my first attempt, I just passed the parseText(json.data) which gives an error about not being able to parse a HashMap.
So my question is: how do I get JSON returned from the RESTClient to be parsed by JsonSlurper?
The RESTClient class automatically parses the content and it doesn't seem possible to keep it from doing so.
However, if you use HTTPBuilder you can overload the behavior. You want to get the information back as text, but if you only set the contentType as TEXT, it won't work, since the HTTPBuilder uses the contentType parameter of the HTTPBuilder.get() method to determine both the Accept HTTP Header to send, as well was the parsing to do on the object which is returned. In this case, you need application/json in the Accept header, but you want the parsing for TEXT (that is, no parsing).
The way you get around that is to set the Accept header on the HTTPBuilder object before calling get() on it. That overrides the header that would otherwise be set on it. The below code runs for me.
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.6')
import static groovyx.net.http.ContentType.TEXT
def client = new groovyx.net.http.HTTPBuilder('myRestFulURL')
client.setHeaders(Accept: 'application/json')
def json = client.get(contentType: TEXT)
def slurper = new groovy.json.JsonSlurper().parse(json)
The type of response from RESTClient will depend on the version of :
org.codehaus.groovy.modules.http-builder:http-builder
For example, with version 0.5.2, i was getting a net.sf.json.JSONObject back.
In version 0.7.1, it now returns a HashMap as per the question's observations.
When it's a map, you can simply access the JSON data using the normal map operations :
def jsonMap = restClientResponse.getData()
def user = jsonMap.get("user")
....
Solution posted by jesseplymale workes for me, too.
HttpBuilder has dependencies to some appache libs,
so to avoid to add this dependencies to your project,
you can take this solution without making use of HttpBuilder:
def jsonSlurperRequest(urlString) {
def url = new URL(urlString)
def connection = (HttpURLConnection)url.openConnection()
connection.setRequestMethod("GET")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("User-Agent", "Mozilla/5.0")
new JsonSlurper().parse(connection.getInputStream())
}