SoapUI Groovy: Using JSONBuilder to create JSON from TestCase properties that contain an Object

Please see updated post here for a simpler solution.

I looked around and couldn’t find a simple solution to creating JSON from test case properties while one of the properties already had a written out object. My requests ended up having quotes where they shouldn’t have, badly formed JSON, or just blank in some areas.

Let’s say this is what my SoapUI TestCase Properties used to look like when grabbed from Excel:

tcPropsExample

So, the JSON is more or less written out for my MyObject property. I also tried different combinations, for example, writing out “MyObject” : {“Date”:…..etc} or { “MyObject” : {“Date” :……etc} and using that as the property value, but nothing worked out of the box like I wanted it to.

Now, I still have other properties in there that I want to make part of my JSON call, in the end I want a structure like:

{
    "A": "value",
    "DefinedObject1": {
        "X": "value",
        "Y": "value"
    },
    "DefinedObject2": {
        "Date": "value",
        "Param1": "value",
        "Param2": "value"
    }
}

I don’t know if there’s a better solution to this, but instead of passing in well formed JSON as a value I write out the JSON using ‘=’ instead of ‘:’ and ‘&’ instead of ‘,’.

Which ends up looking like this in an editor:

json1

Then I use this Groovy script for creating my JSON body:

package qa

public class MyClass {	

	def createJSON(testRunner,testStepLocation) {

		//properties
		def request = testRunner.testCase.getTestStepAt(testStepLocation).getTestRequest()
		def tcProps = testRunner.testCase.getProperties()
		def map1 = [ : ]
		def map2 = [ : ]
		def object1
		
			//grab all the properties from the test case and put them in a map as long as they aren't empty
			for (p in tcProps) {
				if (p.value.getValue() != "") {
					if (p.key.equals('A')) {
						map1.put(p.key, p.value.getValue())
					} else if (p.key.equals('X') || p.key.equals('Y')) {
						map2.put(p.key, p.value.getValue())
					} else if (p.key.equals('MyObject')){
						object1 = p.value.getValue()
					}
				}
			}

			if (object1 != null && object1 != "") {	

			//remove line break characters from the string
			object1 = object1.replaceAll("\\r?\\n","")
			
			//split the string for the object into a new map
			def object1Map = object1.split('&').inject([:]) { map, token ->
				token.split('=').with { map[it[0]] = it[1] }
				map
			        }
			}			
			def builder = new groovy.json.JsonBuilder()

			if (object1 != null && object1 != "") {	
			  def root = builder {
				map1.each() {
					key,
					value -> "${key}" "${value}"
				}
				DefinedObject1 {
					map2.each() {
						key,
						value-> "${key}" "${value}"
					}					
				}	
				DefinedObject2 {		
					object1Map.each() {
						key,
						value -> "${key}" "${value}"
					}
				}
			  }
			} else {  //could add more if/else statements here to cover all scenarios but you get the idea
			  def root = builder {
				map1.each() {
					key,
					value -> "${key}" "${value}"
				}
				DefinedObject1 {
					map2.each() {
						key,
						value-> "${key}" "${value}"
						}					
					}	
				}
			}			
		def json = builder.toPrettyString()
		json = groovy.json.StringEscapeUtils.unescapeJava(json)
		request.setRequestContent(json)
	}
}

I think the comments inline make it pretty self-explanatory but just to clarify this is what happens:

1) Grab all the TestCase properties and split them up into different maps
2) If it’s MyObject as the key (property name) then instead just grab the value and assign it to a string variable
3) Strip said string of any new line characters if not null/empty
4) Fancy code that I got from StackOverflow here that basically just says “Split up my string based on X and Y delimiters and make it a map”
5) If statements to cover different structure if variables are null/empty
6) Create the JSON based on those three maps we just created

Enjoy!

Advertisements

One thought on “SoapUI Groovy: Using JSONBuilder to create JSON from TestCase properties that contain an Object

  1. Pingback: SoapUI Groovy: Splitting out your scripts | the test suite

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s