GroovyShell script needs to call local methods

55 Views Asked by At

I need to create a Script from a String and execute it in the context of the current test class. Here's my simplified code:

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()
        Script script = shell.parse("getOne() + getTwo()")

        when:
        def result = script.run()

        then:
        result == 3
    }
}

This gives me the following error:

No signature of method: Script1.getOne() is applicable for argument types: () values: []

I see that to set variables one can use shell.setProperty but how do I pass the method's implementation to the script?

1

There are 1 best solutions below

0
iKnowNothing On

Of course, as soon as I posted this, I found my answer.

import org.codehaus.groovy.control.CompilerConfiguration
import spock.lang.Specification

class MyTestSpec extends Specification {
    Integer getOne() { return 1 }
    Integer getTwo() { return 2 }

    void 'call script with local methods'() {
        given:
        CompilerConfiguration cc = new CompilerConfiguration()
        cc.setScriptBaseClass(DelegatingScript.name)
        GroovyShell sh = new GroovyShell(this.class.classLoader, new Binding(), cc)
        DelegatingScript script = (DelegatingScript) sh.parse("getOne() + getTwo()")
        script.setDelegate(this)

        when:
        def result = script.run()

        then:
        result == 3
    }
}