Search code examples
automated-testskarate

Utilizing Karate framework to filter a json object based on the presence of a specific nested object


I'm a relatively green engineer, so please forgive me if I misuse terminology or miss something obvious. To the problem-

I'm writing automated tests for QA using the Karate framework, and I'm attempting to take a series of json objects received in a response body, evaluate each of those objects for the presence of a specific deeply nested object, and then create an object variable only containing those objects that have that specific object nested within to be used in later assertions validating a predefined schema within that scenario.

I've tried a few different variations of the following, like adding != null to the deepest object in the filteredResponseObject definition, but all of them end up generating a json variable object that still contains objects that do not have the nested object within them, so are invalid for the assertions later in the scenario

* def responseObjects = $.topLevelObjects[*]
// Other assertions

// creating a filtered Object that only contains topLevelObjects with the specificFourthLevel object present
*def filteredResponseObjects = $.responseObjects[?(@.specificSecondLevelObject[*].specificThirdLevelObject[?(@.specificFourthLevelObject)])]
And assert filteredResponseObjects.length > 0
//additional assertions

The object is created, but as I mentioned, still has topLevelObjects that do not contain the nested object I'm looking for. I've tried some suggestions for CoPilot and Chat GPT, but to no avail. I should also add that I wanted to simply make the object that's tested for in the schema optional, but my tech lead didn't want to use that solution since that schema is utilized in many other feature files. Any help or suggestions would be mightily appreciated.


Solution

  • Instead of using the JsonPath approach, I recommend using the JS array filter approach. If you are not familiar with JS, that's ok things like map() and filter() are very easy to pick up.

    There is a good explanation here: https://stackoverflow.com/a/76091034/143475

    Here's an example:

    * def response =
    """
    [
      {
        a: {
          b: {
            c: 1
          }
        }
      },
      {
        a: {
          b: {
          }
        }
      }
    ]
    """
    * def filtered = response.filter(x => x.a && x.a.b && x.a.b.c == 1)
    

    If you have a hard time understanding this and the linked answer - try to get a friend who knows JS to help.