Forum Discussion

tinoboehme's avatar
tinoboehme
Occasional Contributor
12 years ago

call Script Library Method within dynamic property expansion

Hello,

how to call an own method with in the script library?
One example method from my Script Library (based on this example)

package soapui.utils
class MyUtils {
static def randInt(from = 1, to = 10) {
return (int) from + (to * Math.random())
}
}


I want to expand some strings with a method of MyUtils:

import soapui.utils.*
log.info('<XmlTag>'+MyUtils.randInt(10,20)+'</XmlTag>') // :) return random value
log.info('<XmlTag>'+soapui.utils.MyUtils.randInt(10,20)+'</XmlTag>') // :) return random value
log.info(context.expand('<XmlTag>${=(int)10+290*(Math.random())}</XmlTag>')) // :) return random value
log.info(context.expand('<XmlTag>${=java.util.UUID.randomUUID()}</XmlTag>')) // :) return a UUID
log.info(context.expand('<XmlTag>${=MyUtils.randInt(10,20)}</XmlTag>')) // :( return "<XmlTag>No such property: MyUtils for class: Script2</XmlTag>"
log.info(context.expand('<XmlTag>${=soapui.utils.MyUtils.randInt(10,20)}</XmlTag>')) // :( return "<XmlTag>No such property: soapui for class: Script3</XmlTag>"


why the last two examples don't work?

Regards Tino

6 Replies

  • tinoboehme's avatar
    tinoboehme
    Occasional Contributor
    *push*
    Is there any way to trigger an own method within an dynamic property expansion?

    Regards Tino
  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi Tino,

    Sorry for the slow reply. I tried reproducing this, using your exact code. This line
    log.info(context.expand('<XmlTag>${=MyUtils.randInt(10, 20)}</XmlTag>'))

    doesn't work. But, the error message I get is different from yours:
    Tue Apr 09 13:19:29 CEST 2013:INFO:<XmlTag>No signature of method: static soapui.utils.MyUtils.randInt() is applicable for argument types: (java.lang.Integer, java.lang.Integer) values: [10, 20] Possible solutions: randInt(), randInt(java.lang.Object), randInt(java.lang.Object, java.lang.Object), wait()</XmlTag>

    However, the line below:
    log.info(context.expand('<XmlTag>${=soapui.utils.MyUtils.randInt(10,20)}</XmlTag>')) // :( return "<XmlTag>No such property: soapui for class: Script3</XmlTag>"

    works fine.

    The explanation to this is that scripts written inside property expansions are evaluated as separate scripts (in a vacuum, you could say), and because of this the failing code snippet doesn't recognize that MyUtils has been imported, and thus fails.

    Have you made sure that your script is located in the correct folder, set the scripts preferences correctly ("Script library" in "Preferences" -> "soapUI Pro"), and created the correct package structure (SoapUIHomeFolder/scripts/soapui/utils/MyUtils.groovy)?
  • tinoboehme's avatar
    tinoboehme
    Occasional Contributor
    Hello,

    yes, the script library is set correctly and the package struckture is also okay. Following code is running fine:

    result = soapui.utils.MyUtils.randInt(10,20)
    log.info(result)

    I've the same problem with eval:

    string = "soapui.utils.MyUtils.randInt(10,20)"
    result = Eval.me(string) // groovy.lang.MissingPropertyException: No such property soapui for class: Script1

    The interesting thing is following code is working find in a "Groovy Script TestStep" but NOT inside a method of me Library. Why????

    string = "soapui.utils.MyUtils.randInt(10,20)"
    result = evaluate(string)

    I figured out that the evaluate() method is inside the groovy.lang.GroovyShell Class, but I couldn't find any way to use

    def shell= new groovy.lang.GroovyShell()
    result = shell.evaluate(string) // groovy.lang.MissingPropertyException: No such property soapui for class: Script1

    If I try to create a new object (constructor is present) with the last solution (string = "new soapui.utils.MyUtils()") I get follwing Exception:
    org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script1.groovy: 1: unable to resolve class soapui.utils.MyUtils

    I've send many days in this topic! I really have no more Idea.
    Please Help!!!
  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi,

    I'm sorry to hear you're having problems. It is a bit unclear to me exactly what you're trying to achieve. We don't usually provide support for groovy questions, but if you can explain what you're trying to do on a bigger scale perhaps we can give you some pointers.

    Regards,
    Arian
    SmartBear Support
  • tinoboehme's avatar
    tinoboehme
    Occasional Contributor
    Hello,

    the point is that the ScriptLibrary (C:\Program Files\SmartBear\soapUI-Pro-4.5.1\bin\scripts\soapui\ used in groovy with soapui.*) is not imported within subscripts:

    context.expand('<XmlTag>${=soapui.utils.MyUtils.randInt(10,20)}</XmlTag>')) // return "<XmlTag>No such property: soapui for class: Script3</XmlTag>"
    Eval.me("soapui.utils.MyUtils.randInt(10,20)") // groovy.lang.MissingPropertyException: No such property soapui for class: Script1

    Thus I don't think it is a groovy issue, it is more an issue how the script library is implemented.
    Or you can give me a hint how to import the ScriptLibrary to make the commands above up and running.

    What I want to achieve:
    - use own functions with in the XML's requests like <XmlTag>${=soapui.utils.MyUtils.randInt(10,20)}</XmlTag>
    - import dynamic libraries based on a property e.g.

    Property['Lib'] = "XYZ"
    myLibName = project.getPropertyValue('Lib')
    def myLib = evaluate(new soapui.libs."+myLibName+"(myLibName)")

    This should initialize an object of the class XYZ from the file "C:\Program Files\SmartBear\soapUI-Pro-4.5.1\bin\scripts\soapui\libs\XYZ.groovy" and handover the variable myLibName to the constructor.
    This is working fine with build in groovy mathods / classes but and within an groovy teststep not within own classes, why?
    Do I have to import a class or open a package?

    Regards Tino
  • SmartBear_Suppo's avatar
    SmartBear_Suppo
    SmartBear Alumni (Retired)
    Hi,

    I think your issue is actually in the package import. Initially when I tried your exact first post code, only the following line couldn't be run but if commented out everything executed:

    log.info('<XmlTag>'+soapui.utils.MyUtils.randInt(10,20)+'</XmlTag>')                 // :) return random value


    But when I take out the import and just have the code below in a Groovy script step, everything runs:

    log.info('<XmlTag>'+MyUtils.randInt(10,20)+'</XmlTag>')                              // :) return random value
    log.info('<XmlTag>'+soapui.utils.MyUtils.randInt(10,20)+'</XmlTag>') // :) return random value
    log.info(context.expand('<XmlTag>${=(int)10+290*(Math.random())}</XmlTag>')) // :) return random value
    log.info(context.expand('<XmlTag>${=java.util.UUID.randomUUID()}</XmlTag>')) // :) return a UUID
    log.info(context.expand('<XmlTag>${=MyUtils.randInt(10,20)}</XmlTag>')) // :( return "<XmlTag>No such property: MyUtils for class: Script2</XmlTag>"
    log.info(context.expand('<XmlTag>${=soapui.utils.MyUtils.randInt(10,20)}</XmlTag>')) // :( return "<XmlTag>No such property: soapui for class: Script3</XmlTag>"


    This is in SoapUI Pro v4.5.2.
    Let me know if you still experience the issue.

    Thanks,
    Michael Giller
    SmartBear Software