Rest Assured: java.lang.AssertionError: JSON path body doesn't match - java

The following is the JSON response I get when I hit a url:
{"status":"success","body":[{"id":1,"name":"ALL"},{"id":2,"name":"VW_CMPNY"},{"id":3,"name":"EDT_CMPNY"},{"id":4,"name":"ADD_CMPNY"},{"id":5,"name":"DLT_CMPNY"},{"id":6,"name":"VW_GRP"},{"id":7,"name":"EDT_GRP"},{"id":8,"name":"ADD_GRP"},{"id":9,"name":"DLT_GRP"},{"id":10,"name":"VW_ACCNT"},{"id":11,"name":"EDT_ACCNT"},{"id":12,"name":"ADD_ACCNT"},{"id":13,"name":"DLT_ACCNT"},{"id":14,"name":"VW_INVC"},{"id":15,"name":"EDT_INVC"},{"id":16,"name":"ADD_INVC"},{"id":17,"name":"DLT_INVC"},{"id":18,"name":"ON_RCRD"},{"id":19,"name":"OFF_RCRD"}]}
I'm checking that the JSON response is equal to a .json file I have; this is my code:
URI permissionsUri = new URI(permissionsUrl);
JSONParser jsonParser = new JSONParser();
Object obj = jsonParser.parse(new FileReader("\\db\\seed\\permission.json));
JSONArray expectedJson = (JSONArray) obj;
String expectedStatus = "success";
get(permissionsUri).then().assertThat().body("status", equalTo(expectedStatus)).and().body("body", equalTo(expectedJson));
But I'm getting the following error:
java.lang.AssertionError: JSON path body doesn't match.
Expected: <[{"id":1,"name":"ALL"},{"id":2,"name":"VW_CMPNY"},{"id":3,"name":"EDT_CMPNY"},{"id":4,"name":"ADD_CMPNY"},{"id":5,"name":"DLT_CMPNY"},{"id":6,"name":"VW_GRP"},{"id":7,"name":"EDT_GRP"},{"id":8,"name":"ADD_GRP"},{"id":9,"name":"DLT_GRP"},{"id":10,"name":"VW_ACCNT"},{"id":11,"name":"EDT_ACCNT"},{"id":12,"name":"ADD_ACCNT"},{"id":13,"name":"DLT_ACCNT"},{"id":14,"name":"VW_INVC"},{"id":15,"name":"EDT_INVC"},{"id":16,"name":"ADD_INVC"},{"id":17,"name":"DLT_INVC"},{"id":18,"name":"ON_RCRD"},{"id":19,"name":"OFF_RCRD"}]>
Actual: [{id=1, name=ALL}, {id=2, name=VW_CMPNY}, {id=3, name=EDT_CMPNY}, {id=4, name=ADD_CMPNY}, {id=5, name=DLT_CMPNY}, {id=6, name=VW_GRP}, {id=7, name=EDT_GRP}, {id=8, name=ADD_GRP}, {id=9, name=DLT_GRP}, {id=10, name=VW_ACCNT}, {id=11, name=EDT_ACCNT}, {id=12, name=ADD_ACCNT}, {id=13, name=DLT_ACCNT}, {id=14, name=VW_INVC}, {id=15, name=EDT_INVC}, {id=16, name=ADD_INVC}, {id=17, name=DLT_INVC}, {id=18, name=ON_RCRD}, {id=19, name=OFF_RCRD}]
I don't know why I'm getting the = in place of :. How can I solve this?

When I need to compare response value with restAssurd, I do the following and it works:
Response response = given()
.given().header("Content-Language", "en_US")
.contentType("application/json")
.body(ApiBody)
.when()
.post(baseApiUrl);
JsonPath jp = new JsonPath(response.asString());
log.info(response.asString());
String value = jp.get("valueToCheck").toString();
Assert.assertEquals(valueToCheckFromResponseJson, actualValue, "Value from API doesn't match Value from DB");

The "actual" part looks like the toString call on a collection or an array. You are comparing the contents of the JSONArray class against an actual JSON document. You have to serialize the JSONArray as a JSON document before comparing it against the response of your service.

Related

Why does the String coming in POST request body come with additional quotes and get not a JSON Object

I am calling a RestFul API written in Java that consumes plain text or JSON and returns a response in JSON. I am using gson library to generate and parse my fields. I am calling the api from an Android simulation where I user retrofit2 library and GsonConverterFactory.
The generated String seems fine. I am not using a POJO, just a generic HashMap which I then convert to a String.
Generated gson from Android is {"password":"K16073","userid":"K16073"}
Code given below.
At the API service, the string received is wrapped with additional double quotes.
Printed String including the quotes in the beginning and end "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
Because of this I am getting java.lang.IllegalStateException: Not a JSON Object: "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
I tried to remove the quotes and then I get com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.
/* Android code */
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(myRFReceivingApis.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Map<String, String> userData = new HashMap<>();
userData.put("userid",edtTxtUserId.getText().toString());
userData.put("password",editTxtPassword.getText().toString());
Gson gson = new Gson();
System.out.println(" generated gson " +gson.toJson(userData));
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
textViewResp.setText(response.body().toString());
:
/* End of Android code */
API Service code in Java
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
#Path("login")
public String RFLoginNew(String jsonString) {
String result = jsonString.substring(1, jsonString.length() - 1);
System.out.println(" Json String "+result);
// tried using JsonParser -- line 1 below
JsonObject o = JsonParser.parseString(result).getAsJsonObject();
// tried using Gson gson.fromJson
Gson gson = new Gson();
JsonElement element = gson.fromJson (result, JsonElement.class); //Converts the json string to JsonElement without POJO
JsonObject jsonObj = element.getAsJsonObject(); //Converting JsonElement to JsonObject
// --line 2 below
System.out.println(" RFLoginNew struser "+ jsonObj.get("userid").getAsString());
I am not getting the correct json format. I am not sure what is wrong with the way jsonString is generated.
Cause
You are making double serialization.
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
Here your map gets serialized to json string, and then this json gets serialized a second time when request is sent.
Fix
Serialize only once on frontend - whatever library you are using(i don't do android stuff) should have method where you supply the payload as an Оbject - the method argument should be the map, userData in your case.
call = ApiClient.getInstance().getMyApi().callLogin(userData);
Something like that.
Or double deserialization on backend - deserialize to String, then deserialize the resulting string again to whatever you need.
String jsonString = gson.fromJson(doubleJson, String.class);
Map<String, String> result = gson.fromJson(jsonString, Map.class);
System.out.println(result);

Getting error when trying parse JSON string. org.json.JSONException: A JSONArray text must start with '['

I am trying to parse a JSON string so I could turn it into an array and iterate through each element through indexing.
Below is my code:
String body = "{\"user\":\"d26d0op3-7da5-6ad8\",\"pass\":\"12784949-2b8c-827d\"}";
ArrayList<String> stringArray = new ArrayList<String>();
JSONArray jsonArray = new JSONArray(body);
for (int i = 0; i < jsonArray.length(); i++) {
stringArray.add(jsonArray.getString(i));
}
System.out.println(stringArray);
When I run this code, I get the following error:
Exception in thread "main" org.json.JSONException: A JSONArray text must start with '[' at 1 [character 2 line 1]
I tried formatting my body differently with:
String body = "[{\"user\":\"d26d0op3-7da5-6ad8\",\"instanceId\":\"12784949-2b8c-827d\"}]";
But then I got the following error:
Exception in thread "main" org.json.JSONException: JSONArray[0] is not a String.
How would I go about correctly parsing my JSON?
You might want to read up a bit on the JSON format. Try http://json.org .
In your first case, body is a JSON 'object', not an array. This is similar to a dictionary, or key:value pair map. A JSON object is delimited with { and }.
To parse this body, you would use:
JSONObject job = new JSONObject(body);
String username = job.getString("user");
I think that is probably what you are after.
In the second case, your body is a JSON array that contains one JSON Object. A JSON array is delimited by [ and ]
If you want a JSON array of strings, it would look something like this, instead:
body = "[ \"a\", \"b\", \"c\" ]";
An array of integers would look like:
body = "[ 1,2,3,4 ]";
You can use the ObjectMapper.readValue(String, Class<T>) method to parse a value from a json string to some object. In this case it can be a Map<String, String>:
String body = "{\"user\":\"d26d0op3-6ad8\",\"pass\":\"12784949-827d\"}";
Map<String, String> map = new ObjectMapper().readValue(body, Map.class);
System.out.println(map); // {user=d26d0op3-6ad8, pass=12784949-827d}
If you are expecting a list of some objects:
String body = "[{\"user\":\"d26d0op3-6ad8\",\"pass\":\"12784949-827d\"}]";
List<Object> list = new ObjectMapper().readValue(body, List.class);
System.out.println(list); // [{user=d26d0op3-6ad8, pass=12784949-827d}]
The String body = "{"user":"d26d0op3-6ad8","pass":"12784949-827d"}" is not a array
enter image description here
you can convert to json array like this
String body = "[{"user":"d26d0op3-7da5-6ad8","pass":"12784949-2b8c-827d"}]";

java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject

I hit the API, I get the response as
{"headers":{"Keep-Alive":["timeout=4, max=500"],"Server":["Apache"],"X-Content-Type-Options":["nosniff"],"Connection":["Keep-Alive"],"Vary":["X-Forwarded-For"],"X-XSS-Protection":["1;mode=block"],"Content-Length":["451"],"Content-Type":["application/hal+json"]},"statusCodeValue":200,"body":"{\"id\":\"7199\",\"username\":\"johntest#example.com\",\"start_time\":1583212261,\"expire_time\":1583253338,\"sponsor_profile\":\"1\",\"enabled\":false,\"current_state\":\"disabled\",\"notes\":null,\"visitor_carrier\":null,\"role_name\":\"[Guest]\",\"role_id\":2,}
Then I try to fetch the body.I get till body but I m not able to fetch username under body.Basically my main aim is to get the username.It throws this error
java.lang.ClassCastException: java.lang.String cannot be cast to org.json.JSONObject
Logic that I tried to get username.
ResponseEntity<String> resp = restTemplate.exchange(
reader.getAccountURL() + request.getUsername(),
HttpMethod.GET, entity, String.class);
JSONObject accountDetails = new JSONObject(resp);
Object getBody = accountDetails.get("body");
Object alreadyExits = ((JSONObject) getBody).get("username");
What m I doing wrong?
follow the steps:
get body string: String bodyString= resp.getString("body");
parse bodyString to jsonObject: JSONObject body= new JSONObject(bodyString);
get the username: String usename= body.getString("username");
This should work.
JSONObject is nothing but a map which works on key-value.
If the value returned by a key is map(i.e. key-value pairs) then it can be cast into a JSONObject, but in your case getBody.get("username") returns johntest#example.com which is a simple string and not a key-value pair hence you get this exception
Use: JSONObject getBody = accountDetails.getJsonObject("body")
or you can use:
String bodyString= accountDetails.getString("body");
JSONObject getBody= new JSONObject(bodyString)
and then use Object alreadyExits = ((String) getBody).get("username"); and it should work just fine.

RestAssured JsonPath to String

Is there a way to convert the whole JSON path data to a string in Java?
I am working on APIs and their responses are in JSON format. It is easy to understand the JSON structure through Postman/WireShark but I am trying to run an API request through Java, grab the response, convert the raw response to JSON, convert JSON response to a string format and print it. The method '.getString()' is to access a particular element and not the whole data. The method '.toString()' does not work on JSON data either.
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String id = json.get("id");
log.info("The id is " + id);
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = ???;
log.info("The complete json data is " + complete_json_data);
The code snippet which is mentioned "???" is what I was trying to achieve.
The methods which can convert a JsonPath object into a String are:
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = json.prettify();
and
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = json.prettyPrint();
var obj = { "field1":"foo", "age":55, "city":"Honolulu"};
var myJSON = JSON.stringify(obj);

Can't parse Java JSON string

From my server is get a JSON response like this:
String json = getJsonFromServer();
The server returns this reply (with the double quotes in the beginning and end):
"{\"error\":\"Not all required fields have been filled out\"}";
I then want to get the error field. I have tried to use the JSONObject class to get the string, but it does not work.
System.out.println("The error is: " + new JSONObject().getJSONObject(response).getString("error");
I have try
String response = "{\"error\":\"Not all required fields have been filled out\"}";
JSONParser parser = new JSONParser();
try {
JSONObject json = (JSONObject) parser.parse(response);
System.out.println(json.get("error").toString());
} catch (ParseException ex) {
}
It have working, you can try it and don't forget add json lib json-simple
You seem to be using the wrong JSONObject constructor; in your example, you are trying to fetch an object from a newlay created object - it will never exist.
Try this:
String response = "{\"error\":\"Not all required fields have been filled out\"}";
JSONObject json = new JSONObject( response );
String error = json.getString( "error" );
System.out.println( error );
Yields
Not all required fields have been filled out
edit
Now that you have completely changed the question...
Why not just first strip the first and last char?
So if
String response = "\"{\"error\":\"Not all required fields have been filled out\"}\"";
response = response.substring(1, response.length() - 1));
// Now convert to JSONObject
Your response object has exactly this string?
{"error":"Not all required fields have been filled out"}
The code below printed the expected output:
Object responseObject = "{\"error\":\"Not all required fields have been filled out\"}";
JSONObject jsonObject = new JSONObject(responseObject.toString());
String errorContent = jsonObject.getString("error");
System.out.println(errorContent);

Categories

Resources