SOAPUI 上下文变量 - Groovy 如何使这成为可能?

SOAPUI context variables - How does Groovy make this possible?

很抱歉你们 Groovy 伙计们,如果这是一个有点菜鸟的问题。

在 SOAPUI 中,我可以创建一个 Groovy 脚本,我可以在其中为 运行 上下文定义一个任意变量,以便稍后检索。

context.previouslyUndefinedVariable = 3

def num = context.previouslyUndefinedVariable

Groovy 的什么特性允许将以前未定义的变量添加到这样的对象中?我想了解更多。

非常感谢!

Groovy 具有通过元编程动态添加方法到 class 的能力。

要了解更多信息,请参阅:

接受的答案对 SoapUI 是如何做的解释有点糟糕。

在这种情况下,context总是一些SoapUI库的实例java class(例如WsdlTestRunContext),这些都是[=的实现14=]。您可以检查 context.getClass()assert context in Map.

当您在地图上查找 属性 时,Groovy 使用 getAt 和 putAt 方法。您可以使用多种语法。所有这些都是等价的:

context.someUndef
context.'someUndef'
context[someUndef]
context['someUndef']
context.getAt('someUndef')

context.someUndef = 3
context.'someUndef' = 3
context[someUndef] = 3
context['someUndef'] = 3
context.putAt('someUndef', 3)

我喜欢使用以上任何包含引号的内容,这样 Groovy-Eclipse 就不会将其标记为缺失 属性.

同样有趣的是,Groovy 在检查 get 方法被称为 属性 之前先查找 getAt() 方法。

例如,考虑评估 "foo".class。 String 实例没有名为 class 的 属性,它也没有方法 getAt(String),因此它接下来尝试寻找 "get"它找到了具有该名称的方法,即 getClass(),我们得到了结果:String

但是对于映射,['class':'bar'].class 首先引用方法调用 getAt('class'),这将是 'bar'。如果我们想知道它是什么类型的 Map,我们必须更具体并完整地写:['class':'bar'].getClass() 将是 LinkedHashMap

即使 Map 没有匹配的键,我们仍然必须指定 getClass(),因为 ['foo':'bar'].class 仍然意味着 ['foo':'bar'].getAt('class'),这将是 null.