I hope it’s ok to ask a general groovy question here, which is something I’m trying to do in a Katalon script, but it’s not really anything to do with Katalon itself!
Is there a way to pass a map as a method parameter, and convert each item in the map to a variable?
For example, consider the following…
def map = [name: "Jerry", age: 42, city: "New York"]
myFunction( map )
def myFunction( myMapParameter ) {
def name = myMapParameter.get( "name" )
def age = myMapParameter.get( "age" )
def city = myMapParameter.get( "city" )
def xml = """
<Data>
<Name>${name}</Name>
<Age>${age}</Age>
<City>${city}</City>
</Data>
"""
println xml
}
Sure this works, but the code is ugly. I could change the syntax in the XML to directly call the get methods directly (for example ${ myMapParameter.get( “name” )}), but I don’t like this much either. I really want to keep the XML syntax as it is, if possible, which I think it is (I just don’t know how!).
It must be possible, because the findTestObject method can do it, when you pass a map as the second parameter!
I do not see what you want to achieve. Please elaborate what you want a bit more?
No problem, thanks for helping. What I am trying to do in my function is similar to what you can do with the findTestObject function. For example, consider that I have a simple SOAP web service test, and the request object is saved in the repository as “SOAP Service/MyWebServiceRequest”, with the following request message…
<Data>
<Name>${name}</Name>
<Age>${age}</Age>
<City>${city}</City>
</Data>
One way I could pass the three variables is to create a map and pass the map using the findTestObject function, as follows…
def map = [name: “Jerry”, age: 42, city: “New York”]
WS.sendRequest( findTestObject( ‘SOAP Service/MyWebServiceRequest’, map ) )
I’ve used this mechanism in my web service tests in the past, with a function I created that builds the map by reading from a row of data in a spreadsheet, it does exactly what I want and is very efficient. However, now I need to do something similar in a function of my own. I want to call my function with a map, and have it return XML with the variables substituted within it. Ideally I’d like to use the same ‘syntax’ in my function (${name}), so that it’s familiar to anyone that might want to maintain it in future.
I hope this makes sense, it’s hard to describe simply.
You already know that, but you are know aware that you know that. Read the doc:
Ooh thanks, this gets me much closer to what I want, but can I be greedy and ask if we can take it the final step please?
Using the link you sent, I’ve now got the example code like this…
def map = [name: "Jerry", age: 42, city: "New York"]
myFunction( map )
def myFunction( myMap ) {
def xml = """
<Data>
<Name>${myMap.name}</Name>
<Age>${myMap.age}</Age>
<City>${myMap.city}</City>
</Data>
"""
println xml
}
But what I would really like is to avoid specifying “myMap.” in the placeholders. Is there something I can so that the script would know to use the myMap object, so that I can do…
<Name>${name}</Name>
<Age>${age}</Age>
<City>${city}</City>
???
Try the following example:
// See the Groovy lang doc 1.2.2 "Sharing data between a script and the application"
// at http://docs.groovy-lang.org/latest/html/documentation/guide-integrating.html
// You need to enclose the template String with triple single quotes: ''' ... '''
// You should not use triple double quotes: """ ... """
// because here you do not want Groovy to perform interpolating placeholders like ${name} to values
def xml = '''
<Data>
<Name>${name}</Name>
<Age>${age}</Age>
<City>${city}</City>
</Data>
'''
String result = myFunction(xml, ["name": "Jerry", "age": 42, "city": "New York"])
println result
def myFunction(String template, Map variables ) {
def groovyscript = '"""' + template + '"""' // this line constructs a valid "Groovy script" which contains a single string literal enclosed in a pair of double quotations: """ ... """
def shell = new GroovyShell(new Binding(variables))
return shell.evaluate(groovyscript)
}
Yes, SimpleTemplateEngine is better for daily use.
1 Like
Thanks to you and bionel - either of these solutions will work for me, this is BRILLIANT! I’ve learned a lot today, thanks you you both. This is really going to help me - most appreciated!