SoapUI: Handling JSON in Groovy with the JsonFacade Class

As with XML response data, you may come across situations dealing with JSON where you need a little more than what's offered by the standard JsonPath-based assertions. Fortunately, SoapUI provides the JsonPathFacade class for manipulating and retrieving Json in Groovy script, analogous to the XmlHolder class with Xml data.

In my last post, I looked at a service that returned country ISO codes. One type of request searched on a string and returned any countries with matching names, ISO-2 codes, or ISO-3 codes; here's the response JSON for a request searching on the string "United":

{"RestResponse": {
   "messages":    [
      "More webservices are available at http://www.groupkt.com/post/f2129b88/services.htm",
      "Total [5] records found."
   ],
   "result":    [
            {
         "name": "Tanzania, United Republic of",
         "alpha2_code": "TZ",
         "alpha3_code": "TZA"
      },
            {
         "name": "United Arab Emirates",
         "alpha2_code": "AE",
         "alpha3_code": "ARE"
      },
            {
         "name": "United Kingdom of Great Britain and Northern Ireland",
         "alpha2_code": "GB",
         "alpha3_code": "GBR"
      },
            {
         "name": "United States of America",
         "alpha2_code": "US",
         "alpha3_code": "USA"
      },
            {
         "name": "United States Minor Outlying Islands",
         "alpha2_code": "UM",
         "alpha3_code": "UMI"
      }
   ]
}}

Ideally, we'd want to test that all the names returned for the test request do indeed match our input string.  Here's a short example Groovy script assertion that does that using the JsonPathFacade class (line numbers added by me for the walk-through below):

01  import com.eviware.soapui.support.JsonPathFacade
02  
03  def failCount = 0
04  def jpf = new JsonPathFacade(messageExchange.responseContent)
05  def testArray = jpf.readObjectValue("RestResponse.result[*].name")
06  testArray.each{
07    if(!it.contains("United"))
08    {
09      log.info("    Non-matching name: $it")
10      failCount++
11    }
12  }
13  assert failCount == 0

Let's take a look at it line by line:

After importing the JsonPathFacade class (note the XmlHolder class is in the same package) in line 1, line 3 defines a failCount variable we'll use to keep track of failures and check later in our main pass/fail assertion.

In line 4 we create a new JsonPathFacade object and assign it to the jpf variable.  The JsonPathFacade constructor takes JSON response content (as a string) as its only argument.  Within a Groovy script assertion, we can access response content via the responseContent property of the built-in messageExchange variable and pass that into the constructor.

The readObjectValue() and readStringValue() methods of the JsonPathFacade class are the two you'll probably encounter most frequently.  Both take a JsonPath expression (as a string) as input and return the corresponding JSON content; readStringValue() returns the content as a string while readObjectValue() returns it as an object.

In line 5, we use the readObjectValue() method with the JsonPath expression RestResponse.result[*].name to get the names of all the country entities in our response.  This returns a Groovy ArrayList object that gets assigned to the testArray variable.

The ArrayList class is compatible with Groovy's each() method, so starting in line 6 we use it to iterate through the names contained in the testArray variable.  Line 7 checks each name against our match string ("United" in this case).  If the name doesn't match, we log an informational message (line 9) and increment the failCount variable (line 10).

Finally, once our each() method is finished checking all of the country names returned in the response, we assert the failCount variable should still equal 0 in line 13-- if any of the country names didn't contain "United", the assertion and test step fail.

Just to confirm that our script works as expected, let's look at the output if we change our match string (in line 8) to "States", artificially generating failures:


Groovy assertion results and output

Next time we'll look at a more complex example working with JSON objects.

No comments:

Post a Comment

Please be respectful of others (myself included!) when posting comments. Unfortunately, I may not be able to address (or even read) all comments immediately, and I reserve the right to remove comments periodically to keep clutter to a minimum ("clean" posts that aren't disrespectful or off-topic should stay on the site for at least 30 days to give others a chance to read them). If you're looking for a solution to a particular issue, you're free to post your question here, but you may have better luck posting your question on the main forum belonging to your tool's home site (links to these are available on the navigation bar on the right).