Xetius
Xetius

Reputation: 46844

Verifying Jenkins calls while testing pipeline code

I am writing a Jenkins pipeline library, and am having some difficulties with mocking/validating an existing Jenkins pipeline step.

I am using jenkins-spock by homeaway to unit test, but I think my problem is more Spock related.

import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
import com.company.pipeline.providers.BuildLogProvider

class PublishBuildLogSpec extends JenkinsPipelineSpecification {
    BuildLogProvider buildLogProvider = Mock()
    PublishBuildLog publishBuildLog

    def setup () {
        publishBuildLog = new PublishBuildLog(buildLogProvider: buildLogProvider)
        explicitlyMockPipelineStep('writeFile')
    }

    def "Gets the log file contents for a specific job and build"() {
        when:
            "the call method is executed with the jobName and buildNumber parameters set"
            publishBuildLog.call("JOBNAME", "42")
        then:
            "the getBuildLog on the buildLogProvider is called with those parameters"
            1 * buildLogProvider.getBuildLog("JOBNAME", "42")
    }

    def "the contents of log file is written to the workspace"() {
        given:
            "getBuildLog returns specific contents"
            def logFileText = "Example Log File Text"
            buildLogProvider.getBuildLog(_, _) >> logFileText

        when:
            "publishBuildLog.call is executed"
            publishBuildLog.call(_, _)

        then:
            "the specific contents is passed to the writeFile step"
            1 * getPipelineMock("writeFile").call([file: _ , text: logFileText])
    }

}

This is my unit test. I am attempting to say that writeFile is called with the text matching the contents of logFileText, ignoring what the other parameters are. I have tried numerous combinations, but always seem to get the same or similar response to response of:

Too few invocations for:

1 * getPipelineMock("writeFile").call([file: _ , text: "Example Log File Text"])   (0 invocations)

Unmatched invocations (ordered by similarity):

1 * (explicit) getPipelineMock("writeFile").call(['file':'filename', 'text':'Example Log File Text'])

This is to test this class

import com.company.pipeline.providers.BuildLogProvider

class PublishBuildLog {

    BuildLogProvider buildLogProvider = new BuildLogProvider()

    void setBuildLogProvider(BuildLogProvider buildLogProvider) {
        this.buildLogProvider = buildLogProvider
    }

    def call(def jobName, def buildNumber) {
        def contents = buildLogProvider.getBuildLog(jobName, buildNumber)
        writeFile(file: "filename", text: contents)
    }
}

I am at a loss as to how to validate this call. I have a lot of experience with Java and Junit, but I am relatively new to Spock.

How can I verify this?

Upvotes: 0

Views: 946

Answers (1)

kriegaex
kriegaex

Reputation: 67417

For me your test passes. But there is one thing I find strange: You use jokers in a when: block where you should really use concrete parameters like in the first feature method:

when: "publishBuildLog.call is executed"
publishBuildLog.call(_, _)

Instead you should write:

when: "publishBuildLog.call is executed"
publishBuildLog.call("JOBNAME", "42")

For me this works just fine if I use this as a dummy class in order to make the code compile (because you did not provide the source code):

class BuildLogProvider {
  def getBuildLog(def jobName, def buildNumber) {}
}

Upvotes: 0

Related Questions