Rest Assured - compare json response with local json file - json

I have a local json file test.json
[
{
"id": 1,
"title": "test1"
},
{
"id": 2,
"title": "test2"
}
]
Class to read the json file
public static String getFileContent(String fileName){
String fileContent = "";
String filePath = "filePath";
try {
fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
return fileContent;
}catch(Exception ex){
ex.printStackTrace();
}finally{
return fileContent;
}
}
I use rest assured to make the request and get same json response back
String fileContent= FileUtils.getFileContent("test.json");
when().
get("/testurl").
then().
body("", equalTo(fileContent));
This is what I got from local file
[\r\n {\r\n \"id\": 1,\r\n \"title\": \"test1\"\r\n },\r\n {\r\n \"id\": 2,\r\n \"title\": \"test2\"\r\n }\r\n]
This is the actual response:
[{id=1, title=test1}, {id=2, title=test2}]
Is there any better way to compare those two? I try to do something like fileContent.replaceAll("\\r\\n| |\"", ""); but it just removed all the space [{id:1,title:test1},{id:2,title:test2}]
Any help? Or any ways that just compare the content and ignore newline, space and double quote?

You can use any of the following methods
JsonPath :
String fileContent = FileUtils.getFileContent("test.json");
JsonPath expectedJson = new JsonPath(fileContent);
given().when().get("/testurl").then().body("", equalTo(expectedJson.getList("")));
Jackson :
String fileContent = FileUtils.getFileContent("test.json");
String def = given().when().get("/testurl").then().extract().asString();
ObjectMapper mapper = new ObjectMapper();
JsonNode expected = mapper.readTree(fileContent);
JsonNode actual = mapper.readTree(def);
Assert.assertEquals(actual,expected);
GSON :
String fileContent = FileUtils.getFileContent("test.json");
String def = given().when().get("/testurl").then().extract().asString();
JsonParser parser = new JsonParser();
JsonElement expected = parser.parse(fileContent);
JsonElement actual = parser.parse(def);
Assert.assertEquals(actual,expected);

Related

serialize a json using gson

I am using com.google.gson.JsonObject to send the json inside 'parameters' to a rest endpoint.
{
"parameters":
"{
\"customer\" : {
\"firstName\": \"Temp\",
\"lastName\": \"Temp\",
\"emailAddresses\": [\"temp1#temp.com\"],
\"address\": {
\"street1\": \"123 W Temp St\",
\"city\": \"Temp\",
\"state\": \"Illinois\",
\"zipCode\": \"61122\"
}
},
\"options\" : [\"tv\"]
}"
}
Since Parameters is a json string, I am trying to do this :
JsonObject json = new JsonObject();
json.addProperty("options", ??);
I am not sure how to do it for customer and options.
'options' is a java Set, whereas customer is an object.
You may use:
Gson gson = new Gson();
String json = "{\"parameters\": {\"customer\" ... ";
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
JsonArray options = new JsonArray();
options.add("tv");
jsonObject.add("options", options);
String output = gson.toJson(jsonObject);

Parse JSON and convert object back to JSON

I want to parse a nested JSON structure in Groovy. I would like to parse a sub element structure and then return the string in JSON format.
The Nested JSON structure:
{
"username": "test",
"token": "test1",
"url": "http://www.abc.to",
"testsession":
{
"serverName": "0.0.0.0",
"serverPort": 22,
"remoteUsername": "admin",
"remotePassword": "admin"
},
"deviceapp":
{
"repo": "abc-mvn-a-test-local",
"path": "com/test\/test2\/test3\/mob",
"platform": "ANDROID"
}
}
my code below using JSONSlurper isn't quite giving me what i want:
def slurper = new JsonSlurper().parseText(json)
String deviceAppParsed = slurper.deviceapp
println "deviceAppParsed " + deviceAppParsed
// returns deviceAppParsed {repo=oxp-mvn-a-rel-local, path=com/nagra/opentv/experience/mob, platform=ANDROID}
def jsonDeviceApp = JsonOutput.toJson(deviceAppParsed)
println "IS IT JSON? " + jsonDeviceApp
// returns IS IT JSON "{repo=oxp-mvn-a-rel-local, path=com/nagra/opentv/experience/mob, platform=ANDROID}"
How can i parse the json to retrieve the nested deviceapp structure in raw JSON? Thanks.
:
def slurper = new JsonSlurper().parseText(json)
String deviceAppParsed = slurper.deviceapp
def jsonDeviceApp = JsonOutput.toJson(deviceAppParsed)
I expected println jsonDeviceApp to return:
{"repo": "abc-mvn-a-test-local","path": "com/test\/test2\/test3\/mob","platform": "ANDROID"}
instead it returned:
"{repo=oxp-mvn-a-rel-local, path=com/nagra/opentv/experience/mob, platform=ANDROID}"
just replace String to def in the following line:
String deviceAppParsed = slurper.deviceapp
by using string you are converting Object returned by slurper.deviceapp to string
should be:
def deviceAppParsed = slurper.deviceapp
in this case last line will print json
{"repo":"abc-mvn-a-test-local","path":"com/test/test2/test3/mob","platform":"ANDROID"}

convert Map<Object, List<Object>> dataMap to json using java 8

I have a map with following prototype
Map<Device, List<Message>> dataMap
I want to convert it into json using java 8.
i had tried this :
public static String getJson(Map<Device, List<Message>> data) {
String json = "{" + data.entrySet().stream()
.map(e -> "\"" + e.getKey().getId() + "\"" + ":\"" + String.valueOf(e.getValue()) + "\"")
.collect(Collectors.joining(", ")) + "}";
return json;
but it is retutning only one record when i am trying to convert more than 1 record in map.
e.g.
Map<String, List<String>> mapData = new HashMap<>();
mapData.put("Avy", Arrays.asList("Hello", "Hi"));
mapData.put("Sam", Arrays.asList("Good"));
returns
"{\"1001\":\"[Message{message='You have scheduled monthly check-up.'}]\"}"
Use GSON library's toJSON function.
Its easy and hides the unwanted complexities odf doing it manually.
In this case, you might have to use TypeToken.
Gson gson = new Gson();
Type classType = new TypeToken<Map<Device, List<Message>>>(){}.getType();
String dataMapJson= gson.toJson(dataMap, classType);
Haven't tested the code. This is just to give you a gist.
Try this:
Map<String, Object> data = new HashMap<String, Object>();
data.put( "name", "Mars" );
data.put( "age", 32 );
data.put( "city", "NY" );
JSONObject json = new JSONObject();
json.putAll( data );
System.out.printf( "JSON: %s", json.toString(2) );
output::
JSON: {
"age": 32,
"name": "Mars",
"city": "NY"
}
You can also try to use Google's GSON. Google's GSON is the best library available to convert Java Objects into their JSON representation.

I'm trying to convert my Json Object to pretty format using gson but encountering something odd

JsonObjectBuilder builder = factory.createObjectBuilder().add("input", input);
JsonObject jsonData = builder.build();
String jsonDataString = jsonData.toString();
try {
OutputStream jsonStream = new FileOutputStream(jsonPath);
OutputStreamWriter jsonStreamWriter = new OutputStreamWriter(jsonStream);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyOutput = gson.toJson(jsonData);
System.out.println(prettyOutput);
jsonStreamWriter.write(prettyOutput);
}
catch(Exception e) {}
The output I get is weird:
It adds '"value":' before every string value of a key.
My JSON data is something like this:
{
"input": {
"record0": {
"Active": "",
"Level": "",
"Name": "Pre-Session",
"Description": "",
"Record": "",
"Field": "",
"Std. Rule": "",
"Ext. Rule": "//Updated By: Sukanya Dasgupta On: 25-Jan-2016"
}
}
}
Not an expect but I think the problem is that public String toJson(Object src) loses type information :
This method should be used when the specified object is not a generic
type. This method uses Object.getClass() to get the type for the
specified object, but the getClass() loses the generic type
information because of the Type Erasure feature of Java.

Converting byte array to Json giving avro Schema as input is giving an error

I have a simple JSON
String jsonPayload = "{\"empid\": \"6\",\"empname\": \"Saurabh\",\"address\": \"home\"}";
jsonPayload.getBytes();
I created avro schema
{"namespace": "sample.namespace",
"type": "record",
"name": "Employee",
"fields": [
{"name": "empid", "type": "string"},
{"name": "empname", "type": "string"},
{"name": "address", "type": "string"}
]
}
When I try to compare them I get an error
Exception :
org.apache.avro.AvroRuntimeException: Malformed data. Length is negative: -62
at org.apache.avro.io.BinaryDecoder.doReadBytes(BinaryDecoder.java:336)
at org.apache.avro.io.BinaryDecoder.readString(BinaryDecoder.java:263)
at org.apache.avro.io.ResolvingDecoder.readString(ResolvingDecoder.java:201)
at org.apache.avro.generic.GenericDatumReader.readString(GenericDatumReader.java:430)
at org.apache.avro.generic.GenericDatumReader.readString(GenericDatumReader.java:422)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:180)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152)
at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:240)
at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:230)
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:174)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152)
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144)
Looks like there is problem with String and Charsequence identification. Not able to identify exact problem
bytearraytojson converter method code
public String byteArrayToJson(byte[] avro, Schema schema) throws IOException {
boolean pretty = false;
GenericDatumReader<GenericRecord> reader = null;
JsonEncoder encoder = null;
ByteArrayOutputStream output = null;
try {
reader = new GenericDatumReader<GenericRecord>(schema);
InputStream input = new ByteArrayInputStream(avro);
output = new ByteArrayOutputStream();
DatumWriter<GenericRecord> writer = new GenericDatumWriter<GenericRecord>(schema);
encoder = EncoderFactory.get().jsonEncoder(schema, output, pretty);
Decoder decoder = DecoderFactory.get().binaryDecoder(input, null);
GenericRecord datum;
while (true) {
try {
datum = reader.read(null, decoder);
} catch (EOFException eofe) {
break;
}
writer.write(datum, encoder);
}
encoder.flush();
output.flush();
return new String(output.toByteArray());
} finally {
try {
if (output != null) output.close();
} catch (Exception e) {
}
}
}
Your problem is that the avro has the schema included.
If you want to read the avro you should to use other DataReader, DataFileReader
Here is a example that how read an avro in byte[] format with schema
Scala example:
def deserializeGenericWithSchema(message: Array[Byte]): Seq[GenericRecord] = {
val reader: DatumReader[GenericRecord] = new SpecificDatumReader[GenericRecord]()
val fileReader = new DataFileReader(new SeekableByteArrayInput(message),reader)
extractRec(fileReader,Seq.empty[GenericRecord])
}
#tailrec
def extractRec(fileReader: DataFileReader[GenericRecord], acc: Seq[GenericRecord]):Seq[GenericRecord] = {
if (fileReader.hasNext) {
val newElement = fileReader.next
extractRec(fileReader,acc :+ newElement)
} else {
acc
}
}
Java example:
public List<GenericRecord> deserializeGenericWithSchema(byte[] message) throws IOException {
List<GenericRecord>listOfRecords = new ArrayList<>();
DatumReader<GenericRecord> reader = new SpecificDatumReader<>();
DataFileReader<GenericRecord> fileReader =
new DataFileReader<>(new SeekableByteArrayInput(message),reader);
while (fileReader.hasNext()) {
listOfRecords.add(fileReader.next());
}
return listOfRecords;
}
PD: I have written the solution in scala and then I have traduced to Java, without testing. Maybe the Java solution is not completely perfect
you have to use morphline to convert json to avro.
Here is link.
http://cloudera.github.io/cdk/docs/current/cdk-morphlines/morphlinesReferenceGuide.html#/cdk-morphlines-avro