How to fetch the data from Nested JSON Object using PactDslJsonBody

Reading Time: 3 minutes

This blog will have to help you fetch the data from nested JSON Object using a PactDslJsonBody. 

How to parse nested JSON in Java?

  • A JSON object is an unordered set of key/value pairs. A JSON array is an ordered collection of values. The values could be objects or arrays. Nested JSON is a JSON file with its values being other JSON objects. Accessing nested JSON objects is very much like accessing nested arrays.
  • We will be passing the following JSON as an example to retrieve values for multiple outer and inner keys.
{schemaVersion=2.1, userId=16490fb4-c21c-496c-9b35-696171c49651, body={requestId=5374547d-2310-4190-8b63-0dcedc2138cb, person={eeId=EEID1, personId=080b3662-28d1-444b-87af-f79c7f3ebcde, pendHire={pendHireId=SESSION_ID}, eeo={eeoId=EEO_ID}, acaFiling={nonEmployeeId=ACA_ID, aleMemberId=Ale_ID}, onboarding={personId=ONB_ID}, pdoc={employeeId=f8e8a19b-d842-46ae-8906-3ec454d527c2, cliendId=f8e8a19b-d842-46ae-8906-3ec454d527c2}, identity={accountStoreId=ACCOUNT_ID}, coreWorkflow={jobId=JOB_ID}, puuid=0634a5f8-ad06-41f0-b176-0e25c24ce2ee, userIntegrationKey=59744513-0EE2-4EB9-A562-75855DDB02C8}, products=[BI], policy={}}, dataCenter=dlas1, correlationId=41c2b6a2-8693-4196-b745-a98a10131071, user=Marcus Mason}

JSON Maven dependency

  • We can use any version dependency for suitable code, So Go to MavenRepository and select the latest version dependency.

Fetch the value from Nested Json

  • Read Data From JSON File using object Mapper so we will generate the PACT with dynamic json data.
public MessagePact contract(String fileName, MessagePactBuilder builder) throws IOException {

    PactDslJsonBody body = new PactDslJsonBody();
    // jsonMap is a nested string json
    Map<String, Object> bodyAttribute =
        (Map<String, Object>) jsonMap.get(ConsumerContractConstants.body);
    for (Map.Entry<String, Object> entryJson : jsonMap.entrySet()) {
      if (entryJson.getKey().contains(ConsumerContractConstants.body)) {
        PactDslJsonBody bodyForPerson = new PactDslJsonBody();
        for (Map.Entry<String, Object> entryBody : bodyAttribute.entrySet()) {
          if (entryBody.getKey().contains(ConsumerContractConstants.person)) {
            PactDslJsonBody bodyForPersonId = new PactDslJsonBody();
            for (Map.Entry<String, Object> entryPerson :
                ((Map<String, Object>) bodyAttribute.get(ConsumerContractConstants.person))
                    .entrySet()) {
              bodyForPersonId.stringValue(entryPerson.getKey(), entryPerson.getValue().toString());
            }
            bodyForPerson.stringValue(entryBody.getKey(), bodyForPersonId.toString());
          } else {
            bodyForPerson.stringValue(entryBody.getKey(), entryBody.getValue().toString());
          }
          body.stringValue(entryJson.getKey(), bodyForPerson.toString());
        }
      } else {
        body.stringValue(entryJson.getKey(), entryJson.getValue().toString());
      }
    }
    MessagePact a_user_created_message =
        builder.expectsToReceive("a user created message").withContent(body).toPact();
    return a_user_created_message;
  }
  • This method is self-explanatory here We describe basically what message contains.
  • So Let’s break it down.
expectsToReceive(“a user created message”)This is the description of the interaction.
The provider needs to provide a sample event from a method annotated with this description
withContent(…)Message body
  • Now if we want to fetch the any particular attribute value from above generated pact into Object using HashMap then we use below code.
public Map<String, Object> getStringObjectMap(MessagePact contract)
      throws JsonProcessingException {
    String pact = contract.getMessages().get(0).getContents().valueAsString();
    Map<String, Object> stringObjectMap =
        objectMapper.convertValue(
            objectMapper.readTree(pact), new TypeReference<Map<String, Object>>() {});
    return stringObjectMap;
  }
  • it’s return the json string So help of this we can fetch the every string json values.

Output

{schemaVersion=2.1, dataCenter=dlas1, correlationId=41c2b6a2-8693-4196-b745-a98a10131071, body={"requestId":"5374547d-2310-4190-8b63-0dcedc2138cb","person":"{\"eeId\":\"EEID1\",\"acaFiling\":\"{nonEmployeeId=ACA_ID, aleMemberId=Ale_ID}\",\"identity\":\"{accountStoreId=ACCOUNT_ID}\",\"coreWorkflow\":\"{jobId=JOB_ID}\",\"onboarding\":\"{personId=ONB_ID}\",\"personId\":\"080b3662-28d1-444b-87af-f79c7f3ebcde\",\"puuid\":\"0634a5f8-ad06-41f0-b176-0e25c24ce2ee\",\"pdoc\":\"{employeeId=f8e8a19b-d842-46ae-8906-3ec454d527c2, cliendId=f8e8a19b-d842-46ae-8906-3ec454d527c2}\",\"pendHire\":\"{pendHireId=SESSION_ID}\",\"eeo\":\"{eeoId=EEO_ID}\",\"userIntegrationKey\":\"59744513-0EE2-4EB9-A562-75855DDB02C8\"}","products":"[BI]","policy":"{}"}, userId=16490fb4-c21c-496c-9b35-696171c49651, user=Marcus Mason}
  • Now we fetch the personId attribute value from above nested output using below code :
public static Object productFromPact(Map<String, Object> pact) throws JsonProcessingException {
   String body = pact.get(ConsumerContractConstants.body).toString();
    Map<String, Object> person = getStringObject(body);
 String personPact = person.get(ConsumerContractConstants.person).toString();
Map<String, Object> personId = getStringObject(personPact);
    Object personIdPact = personId.get(ConsumerContractConstants.personId);
return personIdPact
  }

Advantage of PactDslJson

  • Best of all, the effort to create and maintain pacts is significantly lower than integration tests.
  • Creating pacts requires that you define your consumer use cases, which is something that you have to do already to some degree.
  • By codifying those use cases in the form of Pact tests, you get documentation and automated verification more or less for free.
  • Pact has become a standard part of our workflow when developing new service interactions. Being able to have contracts that are kept up to date with the code, while simultaneously being able to verify those contracts automatically and in isolation, is a huge benefit.
  • Pact libraries exist for a number of languages including Java, Python, Javascript, and Ruby.
  • The next time you’re struggling to maintain end-to-end tests, or wondering how to make evolving microservices easier, consider adopting Pact for your service contracts.
  • Contract tests should focus on the messages (requests and responses) rather than the behaviour.
  • Pact test should be data independent.
  • Use pactdsljson for contract testing not functional testing.
  • pactdsljson work with all different different data types.

Reference

https://stackoverflow.com/questions/53047903/reading-data-from-nested-json-object-using-java?rq=1


Knoldus-blog-footer-image

Written by 

Prajjawal is a QA Consultant having experience of more than 1.4 year. He is familiar with core concepts of manual & automation testing using tools like Contract test, Selenium, and Postman Also having knowledge of Core Java, Python and Data Science. He is always eager to learn new and advanced concepts in order to improve himself. He likes to watch web series and play cricket.