Forum Discussion

andrew_net's avatar
andrew_net
Occasional Contributor
9 years ago
Solved

How do I assert one of the objects in an array meets a condition in SoapUI by using JSONPath

Let's say I have a response like below

 

{"errors": [{
   "code": "100",
   "message": "Message for 100",
  },

  {
   "code": "200",
   "message": "Message for 200",
  }

]}

 

I can assert the codes by using JSONPath like below:

 

  Expression: $.errors[0].code

  Expected result: 100

 

  Expression: $.errors[1].code

  Expected result: 200

 

The problem is that the order of the objects in the array may change, i.e. 200 occurs first and 100 occurs after. So, I have to assert something like "the errros should contain an error with code 100 while the error 100 can occur anywhere in the errors array". How do I do this?

 

Currently, I have to use Script assertion to achieve this and I am wondering if there is a better way.

 

Thanks.

 

  • That is a problem we have struggled with as well - I think this solution will work too, if you use expected result '100' for the following jsonpath, it should evaluate true if code 100 is present in the sample json. Basically it is asking to return the code value for any errors element where the .code subelement equals 100...  Of course this will run into problems if there can be multiple errors.code items in the json, but it has proved very useful in our tests.

     

     

    $..errors[?(@.code==100)].code

     

     

    Json used

    {"errors": [{
    "code": "100",
    "message": "Message for 100"
    },
    {
    "code": "200",
    "message": "Message for 200"
    }
    ]}

     

     

     

     

6 Replies

  • Ton646's avatar
    Ton646
    Occasional Contributor

    That is a problem we have struggled with as well - I think this solution will work too, if you use expected result '100' for the following jsonpath, it should evaluate true if code 100 is present in the sample json. Basically it is asking to return the code value for any errors element where the .code subelement equals 100...  Of course this will run into problems if there can be multiple errors.code items in the json, but it has proved very useful in our tests.

     

     

    $..errors[?(@.code==100)].code

     

     

    Json used

    {"errors": [{
    "code": "100",
    "message": "Message for 100"
    },
    {
    "code": "200",
    "message": "Message for 200"
    }
    ]}

     

     

     

     

    • andrew_net's avatar
      andrew_net
      Occasional Contributor

      Thanks a lot, Ton646.

       

      Your solution works! I might stick with the scripting approach though since I have quite few validations and copy & paste of a customized function call is easier than creating multiple JSONPath Match assertions.

       

      While I were validating your solution, I finally figured out why my attempts of the similar approach didn't work. My previous tries were using the following JSONPath:

       

      $..errors[?(@.code=="100")].code

       

      It seemed that this expression considered the quote character (") as part of the value for comparison.

    • andrew_net's avatar
      andrew_net
      Occasional Contributor

      By the way, to get around the problem with multiple items, you can use "JSONPath Count" or "JSONPath Existence Match" instead of "JSONPath Match" as you see fit to assert the "number of occurences" or "existence". So the JSONPath assertions in SoapUI does meet my needs.

      • Ton646's avatar
        Ton646
        Occasional Contributor

        andrew_net wrote:

        By the way, to get around the problem with multiple items, you can use "JSONPath Count" or "JSONPath Existence Match" instead of "JSONPath Match" as you see fit to assert the "number of occurences" or "existence". So the JSONPath assertions in SoapUI does meet my needs.


        Hi - thanks for the suggestion - you are of course correct for cases where the expected count is known beforehand. The JSONPath Count assert didn't work for us in cases where it can be '1 or more' (ie - when it is unpredictable how many occurrences there might be). I would love an assert like xpath where you can do count(  //blah ) >= x.   But then we should have stuck with XML I guess :)

         

        Regards,

        Ton