如何让GroovyShell脚本调用Spock测试类中的本地方法?
问题解决:在Spock测试中让Groovy脚本调用测试类本地方法
你遇到的问题是因为GroovyShell创建的脚本默认运行在独立上下文,无法直接访问测试类的方法。以下是几种可行的解决方式:
方法1:将测试类实例传入脚本上下文
修改测试代码,把当前测试类对象(this)通过setProperty传入Shell,脚本里通过该变量调用方法:
import spock.lang.Specification class MyTestSpec extends Specification { Integer getOne() { return 1 } Integer getTwo() { return 2 } void 'call script with local methods'() { given: GroovyShell shell = new GroovyShell() // 将当前测试实例传入脚本上下文 shell.setProperty('testInstance', this) Script script = shell.parse("testInstance.getOne() + testInstance.getTwo()") when: def result = script.run() then: result == 3 } }
方法2:自定义Binding并设置Delegate
通过自定义Binding,把测试类实例设为脚本的delegate,让脚本可以直接调用方法:
import spock.lang.Specification import groovy.lang.Binding class MyTestSpec extends Specification { Integer getOne() { return 1 } Integer getTwo() { return 2 } void 'call script with local methods'() { given: Binding binding = new Binding() // 设置脚本的delegate为当前测试实例 binding.setDelegate(this) GroovyShell shell = new GroovyShell(binding) Script script = shell.parse("getOne() + getTwo()") // 确保脚本的delegate生效 script.setDelegate(binding.getDelegate()) when: def result = script.run() then: result == 3 } }
方法3:通过MetaClass注入测试类方法
如果需要更灵活地暴露方法,可以通过MetaClass把测试类的方法注入到脚本上下文:
import spock.lang.Specification class MyTestSpec extends Specification { Integer getOne() { return 1 } Integer getTwo() { return 2 } void 'call script with local methods'() { given: GroovyShell shell = new GroovyShell() // 将测试类的方法添加到脚本的metaClass shell.metaClass.getOne = { -> this.getOne() } shell.metaClass.getTwo = { -> this.getTwo() } Script script = shell.parse("getOne() + getTwo()") when: def result = script.run() then: result == 3 } }
原理说明
Groovy脚本的执行依赖Binding上下文,默认Binding不包含测试类的方法或属性。通过上述方式,我们把测试类的实例或方法注入到脚本上下文,让脚本能够找到并调用这些方法。
内容的提问来源于stack exchange,提问作者iKnowNothing
相关产品推荐
相关产品推荐

