Rest-Assured validate each item in a JSON array - rest-assured

Given I have this JSON array:
{
value: ["000", "111", "345", "987"]
}
I want to use Rest-assured to validate the format of the fields using it's given/when/then structure.
given().
queryParam("myparam", myparamvalue).
when().
get(callRoot).
then().
body("value", matchesPattern("[0-9][0-9][0-9]");
How do I get Rest-assured to loop through and apply the test against each value in the JSON array?
I don't know how many values will be in the JSON array. It might be only 1; it might be 100.

You could use JsonPath and do something like the following:
given().
queryParam("myparam", myparamvalue).
when().
get(callRoot).
then().
body("value.*", matchesPattern("[0-9][0-9][0-9]");
See https://github.com/rest-assured/rest-assured/wiki/usage#json-example for more details.
Or you could extract the response as a String, transform it to a JSONObject, extract the JSONArray in the values field, and then apply the regex to each item in the array:
Response response = given().queryParam("myparam", myparamvalue).when().get(callRoot).
JSONObject responseJson = new JSONObject(response.getBody().asString());
JSONArray values = responseJson.getJSONArray("values");
for(int i = 0; i < values.length(); i++) {
String value = values.getString(i);
Assert.assertThat(values, matchesPattern("[0-9][0-9][0-9]"));
}

Related

How to convert body value then validate with RestAssured without extracting response

I have a String value being returned from restAssured that I want to convert to a DateTime then validate. One easy way to do this would be:
MockMvcResponse response = this.given
.accept("application/json")
.body(body)
.when()
.put(link)
.then()
.extract().response()
String jsonStr = response.asString()
Map json = strToJson(jsonStr)
assert(MyFixedDateTime.equals(new DateTime(json.dateAttr))
Is there a way to do this without extracting the response?
Follow this link
I think you gonna need to do something similar:
this.given
.accept("application/json")
.body(body)
.when()
.put(link)
.then().body("dateFieldName", equalTo(MyFixedDateTime.toString()))
You can get the required value using JsonPath and convert the returned string to DateTime.
Response response = RestAssured.given ()
.accept("application/json")
.body(body)
.when()
.put(link);
JsonPath jsonPath = JsonPath.from (response.asString ());
String date = jsonPath.get ("responseRoot.dateField"));
DateTime dt = new DateTime (date);

Use JSONAssert on part of JSON with RESTAssured

I am able to retrieve JSON from a service using RESTAssured.
I would like to use the JSONPath capability to extract JSON and then compare it using JSONAssert.
Here's my example:
#Test
public void doAPITestExample() throws JSONException {
// retrieve JSON from service
Response response = RestAssured.given().get("http://localhost:8081/mockservice");
response.then().assertThat().statusCode(200);
String body = response.getBody().asString();
System.out.println("Body:" + body);
/*
{"datetime": "2018-06-21 17:48:07.488384", "data": [{"foo": "bar"}, {"test": "this is test data"}]}
*/
// able to compare entire body with JSONAssert, strict=false
Object data = response.then().extract().path("data");
System.out.println("Response data:");
System.out.println(data.getClass()); // class java.util.ArrayList
System.out.println(data.toString());
// JSONAssert data with strict=false
String expectedJSON = "{\"data\":[{\"foo\": \"bar\"}, {\"test\": \"this is test data\"}]}";
JSONAssert.assertEquals(expectedJSON, response.getBody().asString(), false);
// How do I extract JSON with JSONPath, use JSONAssert together?
}
Approach 1 - using JSONPath to get JSONObject
How do I get JSONPath to return a JSONObject that can be used by JSONAssert?
In the code example:
Object data = response.then().extract().path("data");
This returns a java.util.ArrayList. How can this be used with JSONAssert to compare to expected JSON?
Approach 2 - parse extracted data with JSONParser
If I do data.toString(), this returns a string that cannot be parsed due to lack of quote handling for string values with spaces strings:
String dataString = response.then().extract().path("data").toString();
JSONArray dataArray = (JSONArray) JSONParser.parseJSON(dataString);
Result:
org.json.JSONException: Unterminated object at character 24 of [{foo=bar}, {test=this is test data}]
Approach 3 - Using JSON schema validation
Is is possible to extract just the data property from the JSON and run that against JSON Schema on just that part?
Note: the entire JSON that is returned is quite large. I just want to validate the data property from it.
What would an example of doing a JSON schema validation look for just the data property from the JSON?
Thanks;
You can use the method jsonPath in your response object.
Example:
// this will return bar as per your example response.
String foo = response.jsonPath ().getString ("data[0].foo");
For more info about JSon path check here.

AFQueryStringPairsFromKeyAndValue not giving proper URL with NSArray?

I am trying to send following parameters in GET method call:
{
query = {
"$or" = (
{
name = yes;
},
{
status = Open;
}
);
};
}
But it seems it is not returning the proper URL:
baseURL/objects?query%5B%24or%5D%5B%5D%5Bname%5D=yes&query%5B%24or%5D%5B%5D%5Bstatus%5D=Open
I was expecting to "Or" my data, but it is doing "And".
I am using AFURLRequestSerialization class.
I have followed this SO, but it gives me all the object without applying any query.
AFNetworking GET parameters with JSON (NSDictionary) string contained in URL key parameter
It was working properly in POST call, but in GET it is not working as expected.
I have resolved this by converting dictionary against query key to a string and adding this string as a value of key query in the dictionary.
So my parameters will look like:
parameters: {
query = "{\"$or\":[{\"name\":\"yes\"},{\"status\":\"Open\"}]}";
}
Then I am passing this dictionary to AFNetworking.

How to get particular json key value from Response Object

I got the response from REST API into Response object after called through RestAssured API.
Response body is json, i want to get the particular key value from that?
Following is the code
Response res = given()
.relaxedHTTPSValidation()
.with()
.contentType(ConfigReader.get("application.json"))
.then()
.get(url);
String rbody = res.body().asString();
How to get particular key value in rbody string?
Response class has method path() using that, user can give the json path to get the particular value.
Eg:-
Response res = given()
.relaxedHTTPSValidation()
.with()
.contentType(ConfigReader.get("application.json"))
.then()
.get(url);
String value = res.path("root.childKey").toString();
root.childKey is the path of the json element
The JasonPath class that is a part of Restassured is the one that I used for my project. First you need to import the JsonPath class using:
import com.jayway.restassured.path.json.JsonPath;
Then you need to pass the JSON string and use it to create the JsonPath object. From the JsonPath object you can use the key to get the corresponding value. The following code will work for you.
Response res = given()
.relaxedHTTPSValidation()
.with()
.contentType(ConfigReader.get("application.json"))
.then()
.get(url);
String rbody = res.asString();
JsonPath jp = new JsonPath( rbody );
String value = jp.getString( "your.key" );
JSON is formated like this {someProprty:"someValue"} so instead of getting it as a String, you'll want to access that specific property. ie: b.body.someProperty
Note: I strongly encourage you to name your response something more like res or response. You aren't going to enjoy having b as your response.
How to access JSON Object name/value?
JSON can also be formatted like {somePropertyThatIsNumerical:1} or can contain arrays.
baseURI="url";
Map<String,String> reqParam=new HashMap<String,String>();
reqParam.put("loginID","abc");
reqParam.put("password","123");
JSONObject reqObjects=new JSONObject(reqParam);
Response response =
given()
.header("Content-Type", "application/json").accept(ContentType.JSON)
.when()
.body(reqObjects.toJSONString()).post("/v1/getDetails")
.then().log().body().extract().response();
String responseBody= response.asString();
JsonPath path=new JsonPath(responseBody);
String key=path.getString("path.key");

Response JSONString order not correctly after reading in iOS

I have JSONString from api as bellow:
[JSONString from api]
But after I read in iOS from Alamofire the order of the JSONString is not correct as api:
[JSON After read in iOS]
How can I keep the JSON format the same order as api?
As explained by #Nimit, JSON format represented in your callback and the API response is of least concern. What you need to care about is that when you are accessing the values from the response, the KEY should be same as seen in the API. No mismatch, not even of the case-sensitive letter, or you will always get the NIL in the response.
To explain it better to you with the use of Alamofire, let's me show you one example:
let APIURL = "https://api.yoururl.com"
Alamofire.request(.GET, APIURL , headers: headers) .responseJSON { response in
let value = response.result.value!
let JSONRes = JSON(value)
let KLValue = JSONRes["Kuala Lumpur"].int!
print(KLValue) //Or call a function to handle the callback
}
Here I am using SwiftyJSON for JSON. In the end, all you want to do is get the data out of the associated keys in the JSON response, no need to worry about how they have been formatted, or what's the order of Keys in the response - most of the time you will get the same as in the API - but in case it changes, need not to worry.
On the another front, to be sure that nothing happens to your app when JSON fields are nil, always put an if-let like this:
if let valueFromJSON = JSONRes["Kuala Lumpur"].string {
someVariable = valueFromJSON
} else {
someVariable = "No Value"
}
Thanks!
You can't do it, unless you write your own JSON parser. Any self-respecting JSON library won't guarantee you the order, if it wants to conform to the JSON spec.
From the definition of the JSON object:
the NSDictionary class represents an unordered collection of objects;
however, they associate each value with a key, which acts like a label
for the value. This is useful for modeling relationships between pairs
of objects.
If you have a jsonObject, such as data, then you can convert to json string like this:
let jsonString = JSONSerialization.data(withJSONObject: data,
options: JSONSerialization.WritingOptions.sortedKeys)
when you use sortedKeys option, the json will be specifies that the output sorts keys in lexicographic order.

Resources