ExpediaGroup / jenkins-spock

Unit-test Jenkins pipeline code with Spock
https://javadoc.io/doc/com.homeaway.devtools.jenkins/jenkins-spock
Apache License 2.0
186 stars 73 forks source link

Script under test doesn't correctly handle field annotated @Field in script's methods #120

Open PavelKa opened 2 years ago

PavelKa commented 2 years ago

Expected Behavior

The tested script correctly handles fields annotated @Field in all methods

Actual Behavior

Methods access the wrong instance of the field

Steps to Reproduce

define script : vars/testFiled.groovy

import groovy.transform.Field
@Field f = "test"
def call(Map _args) {
    node {
        stage("set f") {
            echo(f)
            f = "test2"
            setF()
        }
    }
}
def setF() {
   // field f should contains value "test2" but contains "test" instead
    echo (f)
}

define test:

import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification

class TestFieldSpec extends JenkinsPipelineSpecification {
    def "should echo test test2"() {
        given:
        def testField = loadPipelineScriptForTest("vars/testField.groovy")
        when:
        testField()
        then:
        1 * getPipelineMock("echo")('test')
        1 * getPipelineMock("echo")('test2')
    }
}

Test fails: Too many invocations for:

1 * getPipelineMock("echo")('test') (2 invocations)

Additional Information

Tested with Java 1.8 and 11 and jenkins-spock.version 2.1.5

Script works as expected in Jenkins

mikedld commented 1 year ago

You seem to be overriding the setter for f with setF method declaration, so f = "test2" leads to setF method invocation which doesn't assign a new value to the field. Doesn't look like an issue with this library.

PavelKa commented 1 year ago

You seem to be overriding the setter for f with setF method declaration, so f = "test2" leads to setF method invocation which doesn't assign a new value to the field. Doesn't look like an issue with this library.

Even if I rename setF to echoF then test fails and echoF under test prints test instead of test2, althought skript works well in jenkins.

mikedld commented 1 year ago

Hmm, true. Actually, I was wrong and setF can't be used as a setter because it doesn't even accept a new value as a parameter :)

Doing the assignment directly inside call (outside of node and stage blocks) works, so something weird is going on indeed.