When I have arrays in response, getting proper results using Jayway, but not with io.restassured ? Can I use Jayway and io.restassured together ? Is that an acceptable / good practice?
JSON Response :
{"applications": [
{
"Id": "123",
"amount": "1500"
},
{
"Id": "456",
"amount": "2500"
},
{
"Id": "780",
"amount": "3500"
}
]}
Looking for amount 2500 as my result!
Tried below:
//1st approach to read response form json body
JsonPath jsonPath = res.jsonPath(); System.out.println(jsonPath.get("$.applications[1].amount")); //results null, using io.restassured JsonPath
//2nd approach to read response form json body
JsonPath jsonPath1 = JsonPath.from(res.asString()); System.out.println(jsonPath1.getString("$.applications[1].amount")); //results null, using io.restassured JsonPath
//3rd approach to read response form json body
System.err.println(JsonPath.read(res.asString(),"$.login")); // results 2500, using jaywayJsonPath
There are multiple ways of extracting the values
// Method 1
String res = given().when().get("http://soapractice1.mocklab.io/thing/test").then().extract().asString();
JsonPath js = new JsonPath(res);
System.out.println("The amount is : " + js.get("applications[1].amount"));
// Method 2
Response resp = given().when().get("http://soapractice1.mocklab.io/thing/test").then().extract().response();
JsonPath js1 = resp.jsonPath();
System.out.println("The amount is : " + js.get("applications[1].amount"));
// Method 3
String amount = given().when().get("http://soapractice1.mocklab.io/thing/test").then().extract().jsonPath().get("applications[1].amount");
System.out.println("The amount is : " + amount);
Related
how to assert the json response array contains a substring in a string value.
I have tried this but assertion is failed response.then().body("response.content.Date", Matchers.everyItem(contains("2019-03") ));
my response body is
{
"response": {
"totalSize": 2,
"content": [
{
"requestId": " 931-f8222e",
"name": "gowtham",
"date": "2019-03-06",
"issue": "i have a cause"
},
{
"requestId": " 931-f8222e",
"name": "tharun",
"date": "2019-03-09",
"issue": "has a issue in billing"
}
]
}
}
i want to get all the records in the month(value) and assert the response showing data for given month
I found the solution. You were very close. Instead of using contains which matches full string, you can use containsString to match a substring.
Code:
response.then().body("response.content.date", Every.everyItem(Matchers.containsString("2019-03")));
Suppose i have json string in which there is a json array called data.
The array holds json object of user profile data for example name,age,gender etc.
Now want to parse that json object as per order, for example if the object is
{
"name": "sample name",
"age": "30",
"gender": "male"
}
i want to parse the list as ordered like name,age,gender but with ios,when i convert the json object as dictionary , the order is changed,i know dictionary is not ordered so what is the the alternative to achieve this?
its a third party api so i dont have any hand on it,we have done it in android with linked hash map,but really stuck in swift , the last thing i would want to do is parse with regular expression.
im parsing the json in following way :
var rootData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
if let val = fromList["data"] {
let dataNode = val as! [[String:Any]]
for row in dataNode {
for (key,keyVal) in row {
//here the key is not in order.because when we cast it as dictionary the order gets changed.
}
}
For android we have achieved to do this with following function :
public ArrayList<LinkedHashMap<String, Object>> parseJsonArrayList(String odata, String arrayName) {
ArrayList<LinkedHashMap<String, Object>> mylist = new ArrayList<>();
try {
JSONObject e = new JSONObject(odata);
JSONArray data = e.getJSONArray(arrayName);
for(int i = 0; i < data.length(); ++i) {
JSONObject v = data.getJSONObject(i);
LinkedHashMap<String, Object> map = new LinkedHashMap<>(100, 0.75f, false);
Iterator keys = v.keys();
while(keys.hasNext()) {
String key = String.valueOf(keys.next());
//gph.log("debug4", key);
map.put(key, v.getString(key));
//gph.log("debug4", v.getString(key));
}
mylist.add(map);
}
} catch (JSONException var10) {
var10.printStackTrace();
}
return mylist;
}
Don’t try to order the dictionary. Instead create an array of the keys in the order you desire:
let keys = [“name”, “age”, “gender”]
Then access the dictionary with them:
for key in keys {
let value = dict[key]
// Present the value.
}
That will ensure the order you expect.
As you mentioned you cannot get the ordered data in Dictionary. If possible you can add the "order" key in your JSON like
[
{
"name": "sample name",
"order": 1
},
{
"age": "30",
"order": 1
},
{
"gender": "",
"male": "",
"order": 1
}
]
so that based on the order key you can do the sorting.
Here is my Json
{
"id": "63",
"name": "Magnet",
"price": "₹1250",
"description": "",
"image": [
"catalog/IMG-20150119-WA0012_azw1e3ge.jpg",
"catalog/IMG-20150119-WA0029_6mr3ndda.jpg",
"catalog/IMG-20150119-WA0028_ooc2ea52.jpg",
"catalog/IMG-20150119-WA0026_4wjz5882.jpg",
"catalog/IMG-20150119-WA0024_e38xvczi.jpg",
"catalog/IMG-20150119-WA0020_vyzhfkvf.jpg",
"catalog/IMG-20150119-WA0018_u686bmde.jpg",
"catalog/IMG-20150119-WA0016_c8ffp19i.jpg"
],
"thumb_image": [
"cache/catalog/IMG-20150119-WA0012_azw1e3ge-300x412.jpg",
"cache/catalog/IMG-20150119-WA0029_6mr3ndda-300x412.jpg",
"cache/catalog/IMG-20150119-WA0028_ooc2ea52-300x412.jpg",
"cache/catalog/IMG-20150119-WA0026_4wjz5882-300x412.jpg",
"cache/catalog/IMG-20150119-WA0024_e38xvczi-300x412.jpg",
"cache/catalog/IMG-20150119-WA0020_vyzhfkvf-300x412.jpg",
"cache/catalog/IMG-20150119-WA0018_u686bmde-300x412.jpg",
"cache/catalog/IMG-20150119-WA0016_c8ffp19i-300x412.jpg"
],
"specifications": [
{
"Fabrics": [
"Pure chiffon straight cut suits 48" length"
]
},
{
"MOQ": [
"Minimum 10"
]
}
]
}
In above json string the "specification" arraylist has dynamic number of key and each key has dynamic number of values
So how can parse this? Please help if anyone knows this...
Thanks in advance
There are multiple ways to do parsing. In your case specifications should be an array, so you'll be able to loop on each items.
You might want to :
Create your own JSON parse class / methods ;
Use an existing library to parse JSON.
For the second option, you can give a look at the following :
https://github.com/Wolg/awesome-swift#jsonxml-manipulation
var yourJson = data as? NSDictionary
if let id = yourJson.valueForKey("id") as String
{
//save your id from json
}
if let name = yourJson.valueForKey("name") as String
{
//save your name
}
...
if let images = yourJson.valueForKey("image") as NSArray
{
for im in images
{
//save image
}
//the same for all othe images
}
... And so on...
You should also watch some tutorials, to understand the basics of JSON parsing..
https://www.youtube.com/watch?v=MtcscjMxxq4
I am new to SwiftyJSON, and I'm having some trouble with it. I can get it to return the entire JSON file as a string, but the moment I try to parse it, I keep getting empty variables back, and I'm not sure what I'm doing wrong.
This is the formatting of my JSON file:
[
{
"entryID": 1,
"from": "String",
"to": "String",
"value": "String"
},
{
...
},
...
]
And this is roughly what I want to do with it (in quite inelegant code, I do apologise, I'm new to Swift):
for entry: JSON in indexJSON.arrayValue {
var vEntryID: Int
var vFrom: String
var vTo: String
var vValue: String
for (dictKey: String, dictVal: JSON) in entry.dictionaryValue {
if(dictKey=="entryID") {vEntryID = dictVal.intValue}
if(dictKey=="from") {vFrom = dictVal.stringValue}
if(dictKey=="to") {vTo = dictVal.stringValue}
if(dictKey=="value") {vValue = dictVal.stringValue}
}
someSwiftObject[vEntryID]["from"] = vFrom
someSwiftObject[vEntryID]["to"] = vTo
someSwiftObject[vEntryID]["value"] = vValue
}
However, this block never executes at all, because indexJSON.arrayValue is always empty.
When I try to run the following, it correctly prints the complete file contents to the console:
let indexJSON = JSON(content!)
println(indexJSON.stringValue)
But when I try to go deeper, to fetch any element, it returns nothing:
if(indexJSON.arrayValue.isEmpty==true) {println("indexJSON.arrayValue is Empty")}
if(indexJSON[0].arrayValue.isEmpty==true) {println("indexJSON[0].arrayValue is Empty")}
if(indexJSON[0].dictionaryValue.isEmpty==true) {println("indexJSON[0].dictionaryValue is Empty")}
if(indexJSON[0]["entryID"]==nil) {println("indexJSON[0][\"entryID\"].stringValue is Empty")}
Output:
indexJSON.arrayValue is Empty
indexJSON[0].arrayValue is Empty
indexJSON[0].dictionaryValue is Empty
indexJSON[0]["entryID"].stringValue is Empty
I'd be grateful for any help! What am I doing wrong?
I checked SwiftyJSON source code and I think I know where the problem is.
I suppose that you are using String to initialize the JSON object like this
let s = "{\"entryID\": 1,\"from\": \"String\",\"to\": \"String\",\"value\": \"String\"}"
let j = JSON(s)
In this case the JSON object is actuall given a type "String", not Array. That's why it's not iterable and its arrayValue is empty.
To do what you want to do, you need to initialize it with an Array object:
let arr = [
[
"entryID":1,
"from":"String",
"to":"String",
"value":"String",
]
]
let j2 = JSON(arr)
Now j2 is an array JSON object and iterable.
SwiftyJSON can only be initialized with NSData and object. So if you want to initialize it with a String you need to do this:
if let data = s.dataUsingEncoding(NSUTF8StringEncoding) {
let j = JSON(data:data)
println(j)
}
first of all, make sure the format of your json string is correct. in your question, your json string is a array, just format the string like this(the content is from my code):
let jsonStr = "[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"
then you can use SwityJson to get the array object, like this:
let strData = jsonStr.data(using: String.Encoding.utf8, allowLossyConversion: false)
let json = JSON(data: strData!)
for object in json.arrayValue {
let name = object["name"].string
}
Take a look at the documentation here: https://github.com/lingoer/SwiftyJSON#loop
You are iterating it incorrectly. You should be iterating over the array with a for loop like this:
for (index: String, subJson: JSON) in json {
//Do something you want
}
When using the Alamofire Framework, my responses don't seem to be getting parsed correctly. The JSON response I get has some keys that appear to not be strings, and I don't know how to reference them/get their values.
Here is the part of my code that makes the call:
var url = "http://api.sandbox.amadeus.com/v1.2/flights/low-fare-search"
var params = ["origin": "IST",
"destination":"BOS",
"departure_date":"2014-10-15",
"number_of_results": 1,
"apikey": KEY]
Alamofire.request(.GET, url, parameters: params)
.responseJSON { (_, _, json, _) in
println(json)
}
}
And here is the first section printout when that function is called
Optional({
currency = USD;
results = ({
fare = {
"price_per_adult" = {
tax = "245.43";
"total_fare" = "721.43";
};
restrictions = {
"change_penalties" = 1;
refundable = 0;
};
"total_price" = "721.43";
};
...
});
});
You'll notice that results is not "results", but "price_per_adult" is the correct format. Is there some step I'm missing? When I cast it to NSDictionary it doesn't do anything to help the key format either.
I also tried the same endpoint in javascript and ruby, and both came back without problem, so I'm fairly confident that it is not the API that is causing problems.
Those keys are still Strings, that's just how Dictionarys are printlnd. It looks like it will surround the String in quotes when printing it only if it contains non-alphanumeric characters (_ in this case). You can test this by manually creating a Dictionary similar to the one you're getting back from your API request and then printing it:
let test = [
"currency": "USD",
"results": [
[
"fare": [
"price_per_adult": [
"tax": "245.43",
"total_fare": "721.43"
],
"restrictions": [
"change_penalties": 1,
"refundable": 0
],
"total_price": "721.43"
]
]
]
]
println(test)
Outputs:
{
currency = USD;
results = (
{
fare = {
"price_per_adult" = {
tax = "245.43";
"total_fare" = "721.43";
};
restrictions = {
"change_penalties" = 1;
refundable = 0;
};
"total_price" = "721.43";
};
}
);
}