2

I'm using rest-assured to test an API. I want to handle a scenario where a key might not exist

Given:

{
  "shop":{
     "shopId":1892929,
     "name":"bobs shop",
     "type":"grocery"
  }
}

...in which type key is sometimes not present, I am trying to handle as follows, using theJSONObject has method: https://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)

//restassured code yields response, passed into a JSONObject
JSONObject jsonObj = new JSONObject(response);

if(jsonObj.has(jsonObj.getJSONObject("shop").getString("type"))){
             logger.info("Shop type found as: " + jsonObj.getJSONObject("shop").getString("type"));
}

This code block always evaluates to false even when type is present.

Where am I going wrong?

2
  • .getString("type") returns grocery in your case (developer.android.com/reference/org/json/…) and grocery is not a key in jsonObj.
    – pavelsaman
    Commented Apr 23, 2021 at 9:35
  • @pavelsaman you're right, shop and type are both keys. So I want to check if type exists, and if so, get its key
    – Steerpike
    Commented Apr 23, 2021 at 9:42

2 Answers 2

3

You just get Response object from your call and do:

public class Test {

    public static void main(String[] args) {
        Response response = RestAssured
                .get("https://mocki.io/v1/22617277-2eca-4fcf-b7e2-8c80851ef45d");
        if(response.path("shop.type") == null){
            System.out.println("key does not exist");
        }else{
            System.out.println(response.path("shop.type").toString());
        }
    }

}

You can have more complicated jsonpath query. For example if you treat having field with null value in different way than having no field at all you can use find in your jsonpath like I'm showing below:

if(response.path("shop.find{it.getKey() == 'type'}") != null){
    System.out.print("Key exists ");
    if(response.path("shop.type") == null){
        System.out.println("but have null value");
    }else{
        System.out.println("and have not-null value");
    }
}else{
    System.out.println("Key does not exist");
}
2

Example json:

{
    "priceOne": 1034,
    "priceTwo": {"new":2},
    "priceThree": 7282
}

Checking the value of "new"

       Response response =RestAssured.get("https://newnnnnnnn.free.beeceptor.com").
                        then().extract().response();                
       JSONObject jsonObj = new JSONObject(response.asString());
       String val = (jsonObj.getJSONObject("priceTwo").has("new")) ? response.jsonPath().getString("priceTwo.new"):"not foun";
        
        System.out.println(val);

Try JSONObj.hetJsonobject

As mentioned in above comment you can use response.path("shop.type") == null ? true : false also . But shop.type returns null for non existence and also for {"type": null}

4
  • 1
    I think the other factor that would drive whether to use the JSONObject.has() or the Response.path() check would be how the value is being used. If you're doing assertions around the JSON object's shape and values, then using the JSONObject makes sense, and keeps similar code close to itself. The path() check would make sense if you're getting very different JSON from the endpoint, and you can use a key to determine which path to use.
    – ernie
    Commented Apr 23, 2021 at 15:46
  • 1
    It depends on also how you're going to treat that data. In some situations having no field or having the field with null value might mean the same.
    – Alexey R.
    Commented Apr 23, 2021 at 17:13
  • 1
    @ernie basically you can come up even with the only path() method. Some more advanced querying technique is being involved there. See my update.
    – Alexey R.
    Commented Apr 23, 2021 at 18:08
  • @AlexeyR. I get you can do it using only path(). My comment was saying you might pick the JSONObject approach if you're doing other things with the JSONObject as well, not just checking for the existence of a key.
    – ernie
    Commented Apr 27, 2021 at 22:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.