Converting JSON file to string in RestAssured (Java) - java

I'm using IntelliJ to learn RestAssured; this is completely new territory for me. I have a simple .json file in place and I want to have a API Response to assert if it's the same as the mentioned .json file.
Basically: If the output of the call equals what I have in the json file, it's all good.
I used the demo restapi.demoqa.com for quick reference. This is what I have right now:
#Test
public void ComparewithJSONinResources()
{
String CityResponse = ?????
RestAssured.baseURI = "http://restapi.demoqa.com/utilities/weather/city";
RequestSpecification httpRequest = RestAssured.given();
Response response = httpRequest.request(Method.GET, "/Hyderabad");
String responseBody = response.getBody().asString();
System.out.println(responseBody);
Assert.assertTrue(responseBody.equals(CityResponse));
response.body();
}
I have the .json file in place called CityResponse.json. For easy reference, say on the location c:/CityResponse.
Is it possible to convert the Json file to a string to assert that the API and the JSON are equal?

Comparing JSON as String will never give accurate results, as you will possibly see inconsistency in space, tabs (indentation), property (key-value pair) sequencing etc. Your best bet is to parse JSON into POJO using one of the many popular libraries (Ex. Jackson, GSON etc). And this deserialization you need for both RestAssured Http response & one you are reading from .json file, and once you have two java objects, use standard Java comparision by overriding equals method.

Related

How to extract JSON fields from an api

I have an api which returns data in the below format when i use the clientbuilder get():
final Response response = ClientBuilder.newClient().target("url").queryParam("CustomerQuery", jsonarr).request(MediaType.APPLICATION_JSON).get();
String actual = response.readEntity(String.class);
System.out.println(actual);
Result:
{"_id":{"timestamp":1649320244,"date":"2022-04-07T08:30:44.000+00:00"},"ScheduleTime":"2022-04-07T09:50:00.000+00:00","History":[{"Status":"Pending","Time":"2022-04-07T08:30:44.011+00:00"}],"MyDetails":{"Query":"query1^^","name":"NEH","address":"XXX","Format":"xml","Version":"2"}}
{"_id":{"timestamp":1649320255,"date":"2022-04-07T08:30:55.000+00:00"},"ScheduleTime":"2022-04-07T09:50:00.000+00:00","History":[{"Status":"Pending","Time":"2022-04-07T08:30:55.011+00:00"}],"MyDetails":{"Query":"query2^^^","name":"ABC","address":"YYY","Format":"xml","Version":"1"}}
I need to extract fields under MyDetails in the above string and i tried using :
final Response response = ClientBuilder.newClient().target("url").request(MediaType.APPLICATION_JSON).get();
JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
System.out.println(jsonReader.readObject());
Please let me know how can i extract the fields.
If you have questions about how to use a JsonObject, read the Javadoc https://docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
JsonObject o = jsonReader.readObject();
JsonObject details = o.getJsonObject("MyDetails");
// details.get...
Alternatively, use a different http client like Retrofit that encourages direct object mapping
There are many ways to do what you want to do. I will just describe some of them. You can use several Json parsing libraries. The most popular ones are Json-Jackson also known as faster XML (See link here). You can use method readValue of ObjectMapper class. For class parameter you can use Map.class or your custom written class that will reflect the structure of your Json.
Than there is Gson library, with its user guide
But also if you want a simplistic solution, I wrote my own open-source library that includes JsonUtils class that is a thin wrapper over Json-Jackson library that gives you a very simple solution. In your case it may look like this (assuming variable json is a String that contains your Json string):
try {
Map<String, Object>map = JsonUtils.readObjectFromJsonString(json, Map.class);
Map details = map.get("MyDetails");
} catch(IOException ioe) {
...
}
Map details will contain a map with all your keys and values from section "MyDetails". If you want to use this library here is where to get it: Its called MgntUtils and you can get it on Github with Javadoc and source code. It is available as maven artifacts as well. Here is a Javadoc for JsonUtils class

Interpolate JSON values into a string

I am writing an application/class that will take in a template text file and a JSON value and return interpolated text back to the caller.
The format of the input template text file needs to be determined. For example: my name is ${fullName}
Example of the JSON:
{"fullName": "Elon Musk"}
Expected output:
"my name is Elon Musk"
I am looking for a widely used library/formats that can accomplish this.
What format should the template text file be?
What library would support the template text file format defined above and accept JSON values?
Its easy to build my own parser but there are many edge cases that needs to be taken care of and I do not want to reinvent the wheel.
For example, if we have a slightly complex JSON object with lists, nested values etc. then I will have to think about those as well and implement it.
I have always used org.json library. Found at http://www.json.org/.
It makes it really easy to go through JSON Objects.
For example if you want to make a new object:
JSONObject person = new JSONObject();
person.put("fullName", "Elon Musk");
person.put("phoneNumber", 3811111111);
The JSON Object would look like:
{
"fullName": "Elon Musk",
"phoneNumber": 3811111111
}
It's similar to retrieving from the Object
String name = person.getString("fullName");
You can read out the file with BufferedReader and parse it as you wish.
Hopefully I helped out. :)
This is how we do it.
Map inputMap = ["fullName": "Elon Musk"]
String finalText = StrSubstitutor.replace("my name is \${fullName}", inputMap)
You can try this:
https://github.com/alibaba/fastjson
Fastjson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Fastjson can work with arbitrary Java objects including pre-existing objects that you do not have source-code of.

How to consider JSON structure when write into file

I want to save the entities in our program into .json files to get a better connection between backend and our Angular frontend. For this, I wrote some tests and during the execution, the structure is saved in the files as desired.
The structure is sampled by
ObjectMapper objectMapper = new ObjectMapper();
try{
ObjectWriter writer = objectMapper.wrtier(new DefaultPrettyPrinter());
String result = objectMapper.writerWirthDefaultPrettyPrinter().writeValueAsString(new OurObject());
writer.writerValue(new File("path"), result);
}
What I got
"{\r\n \"firstProp\": something,\r\n \"secondProp\": anything,\r\n...
But I want, that the file contains the classical JSON structure to make it better readable, this means:
{
"firstProp": something,
"secondProp": anything,
...
What can I do, to write it in the desired JSON structure?
Thanks for any help
Matthias
You're double-encoding the json string
Remove writeValueAsString and try to directly use writer.writerValue(file, object)
But if you're emitting this from a Java backend, it's typically best practice to serve it from an HTTP request, not as a file to any front-end

Android - Accessing JSON children from a URL

I'm in the process of converting my website to an Android app and one of the pages' data currently is populated via JSON in my website. The way it works is that the URL generates a different JSON data with the same structure based on the passed ID. I already have the logic for passing the ID to the URL. Now I want to read the data through Java code and parse the JSON children and its values in it.
I have a URL that leads to the JSON file in textual form, but I'm not sure how to go about reading the data from it and accessing the child nodes based on the JSON key.
So I guess what I'm asking is what is the usual approach for this procedure? I see a lot of different examples, but none of which are applicable to my problem.
Anyone have any suggestions as to how I should approach this?
JSONObject = new JSONObject(yourjsonstring);
Now you have your Json Object...
If your Json start with array use this:
JSONArray = new JSONArray(yourjsonarray);
You can use existing libraries to parse JSON, gson or Moshi are two solutions.
The way you go about parsing the JSON is as followed
First you need to make pojo's with the same structure as the JSON file.
then you can parse it to java code via the fromJSON() method, this will make new objects and fill it with the data from the JSON.
gson example for clarification:
Gson gson = new Gson();
Response response = gson.fromJson(jsonLine, Response.class);
where jsonLine = your json file and the Response.Class the pojo in which you want to json to load.
Now you have the JSON values as Java classes in response.
If you're using Retrofit and OkHTTP to perform the network calls i suggest you use Moshi as it's also from Square and claimed to work faster and better than gson. (if you want to know why you can leave a comment).
I think what you're trying to do is this
on post execute method do the following
#Override
protected void onPostExecute(String result) {
String status = "";
String message = "";
String tag = "";
String mail = "";
try {
JSONObject jsonResult = new JSONObject(result);
status = jsonResult.optString("status");
message = jsonResult.optString("message");
tag = jsonResult.optString("tag");
mail = jsonResult.optString("mail");
} catch (JSONException e) {
e.printStackTrace();
}
of course your json array contains different keys
Just reolace them with yours

Unit Testing Download CSV in Spring

I am writing a unit test for an endpoint in Spring which sends a csv file as the response. I am able to do checks like checking Status of the respone and the content type, but how can I compare the contents of the CSV? I tried to convert the response to string and do the comparison but without any success. Can any one point me in the right direction?
Here is what I tried:
public void testDownloadCSV() throws Exception {
RequestBuilder request = MockMvcRequestBuilders.get
(getRequestMapping("/downloadCSV/" + ID))
.contentType(contentType);
ResultActions result = getMockMvc().perform(request);
String csvString = "CSV Data goes here";
String resultString=content().toString();
if (log.isDebugEnabled()) {
result.andDo(print());
Assert.assertTrue(csvString.equals(resultString));
}
// tests:
result.andExpect(status().isOk()).andExpect(content().contentType
(contentType));
}
Not sure what kind of differences are you seeing when your are comparing String contents. Common problem is lack/presence of whitespace characters.
If that's your case, Just use Java library called Hamcrest to compare your strings this way:
assertThat(actualContent, equalToIgnoringWhiteSpace(expectedContent));
If your logic is not order sensitive, I am afraid you'll need parse the CSV strings first into Lists, sort them and compare them afterwards.

Categories

Resources