# Comparing JSON responses using JsonAssert Library - Lenient Mode

In one of the earlier post, we studied about  [Extracting a JSON Response with RestAssured](https://restservicestesting.blogspot.com/2016/10/extracting-json-response-with-rest.html), before following this tutorial, I would recommend reading the previous  [blogs](https://restservicestesting.blogspot.com/) . 

I would assume that everyone following this tutorial has knowledge of Java and TestNG. If you need help then please follow tutorials on  [Java](http://toolsqa.com/java/java-tutorial/)  and  [TestNG](http://toolsqa.com/selenium-webdriver/testng-tutorial/) .

In this post, we will learn about comparing JSON Responses using  [JSONAssert](https://github.com/skyscreamer/JSONassert) Library. 

Once the response is extracted we will store it into Response class and later verify the entire response using a single assert statement instead of comparing specific attributes.

The disadvantage of directly comparing the response as string without JSONAssert is as follows:
- 
If we compare two jsons by simply comparing the json string then it fails to let us know where exactly the comparison has failed. It will also mark json as failed if the order of array elements in json is different. 

However if use JSONAssert Library, it will let us know the exact difference where the comparison between to json string has failed as well as not mark the test as failed if the order of array elements in an array is different if the comparator mode is lenient and if kept as strict then it mark test as failed if the order is different.

We will be using  [findplacefromtext](https://developers.google.com/maps/documentation/places/web-service/search?hl=en_GB)  Google Map API. Follow the create API Key  [Article](https://developers.google.com/maps/documentation/javascript/get-api-key)  for generating your key.

Now let's look at an example where we will search for a particular Railway Station in Mumbai City and then assert the expected response present in  [expectedResponse.txt](https://gist.github.com/ashwink-tech/f935b3ed561120108e5e8f89263074b1)  file to the actual response using JsonAssert Library.

We will need to add following dependencies to the pom.xml of our maven project apart from the others mentioned in the earlier [article](https://restservicestesting.blogspot.com/2019/01/automate-testing-of-rest-services-using.html) 

```xml
<dependencies>
  <dependency>
    <groupId>org.skyscreamer</groupId>
    <artifactId>jsonassert</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
  </dependency>
</dependencies>

``` 


```java
import static io.restassured.RestAssured.basePath;
import static io.restassured.RestAssured.baseURI;
import static io.restassured.RestAssured.given;
import static java.nio.file.Files.readAllBytes;
import static java.nio.file.Paths.get;

import java.io.IOException;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class JSONAssertTest {
  @BeforeClass
  public void setBaseUri() {

    baseURI   = "https://maps.googleapis.com";
    basePath  = "/maps/api/place/findplacefromtext/json";
  }

  @Test
  public void test01() throws IOException {
    var expectedResponse = new String(readAllBytes(get("src/test/java/expectedResponse.txt")));
    var actualResponse =
        given()
            .param("input", "Chhatrapati Shivaji Maharaj International Airport")
            .param("inputtype","textquery")
            .param("fields", "formatted_address,name,rating,opening_hours,geometry")
            .param("key", "xyz")
            .when()
            .get()
            .asString();
    JSONAssert.assertEquals(expectedResponse, actualResponse, JSONCompareMode.LENIENT);
  }
}
``` 
In **setBaseUri** method, we are simply setting the default URI  to use in our tests and also setting the **basePath** of the API.

Now when we write out a test that calls an API (as we will do in the next step), we don’t have to type in the basePath in the **get()** call.

In **test01** method, we are using the  **given - when - then** format. 
We start with **given** method and specify input, inputtype, fields and key parameter using the **param** method then we use the **when** method and use the **get** method to call findplacefromtext API. 

Remember that we set the defaults for the base URI and base path , so the full address of the API that is actually being called is as follows:

```
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input="Chhatrapati Shivaji Maharaj International Airport"&inputtype="textquery"&fields="formatted_address,name,rating,opening_hours,geometry"&key="xyz"
``` 
Now we store the response in **actualResponse** variable as a String. After the response is stored we compare it with **assertEquals** function of JSONAssert Library.

In this case, the test will pass as **expectedResponse** will match the **actualResponse**.


### Failure Scenario

Now lets see another case where we change the expected response a bit. You can find the expected response in the  [expectedresponse.txt](https://gist.github.com/ashwink-tech/b6de7e1526ffa074090e70402f23d96b) file. 
This file is different than the one which we used earlier. In this case we changed the name of Airport in the expectedresponse.txt file from 
> 
Chhatrapati Shivaji Maharaj International Airport
 
To 

> 
Chhatrapati Shivaji Maharaj Domestic Airport.

Now when we run the above test again, it will fail and it will specify exactly where the response did not match which we can view in the following output.

```
java.lang.AssertionError: candidates[formatted_address=Mumbai, Maharashtra 400099, India].name
Expected: Chhatrapati Shivaji Maharaj Domestic Airport
     got: Chhatrapati Shivaji Maharaj International Airport


	at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:417)
	at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:394)
	at JSONAssertTest.test01(JSONAssertTest.java:37)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
	at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
	at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
	at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
	at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
	at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.testng.TestRunner.privateRun(TestRunner.java:794)
	at org.testng.TestRunner.run(TestRunner.java:596)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
	at org.testng.SuiteRunner.run(SuiteRunner.java:276)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
	at org.testng.TestNG.runSuites(TestNG.java:1063)
	at org.testng.TestNG.run(TestNG.java:1031)
	at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
	at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)


===============================================
Default Suite
Total tests run: 1, Passes: 0, Failures: 1, Skips: 0
===============================================

``` 
In the next post, we will learn to use the strict mode and see how it works.


