4

Currently I'm trying to register findFiles step. My set up is as follows:

src/
    test/
        groovy/
            TestJavaLib.groovy
vars/
    javaLib.groovy
javaApp.jenkinsfile

Inside TestJavaApp.groovy I have:

...
import com.lesfurets.jenkins.unit.RegressionTest
import com.lesfurets.jenkins.unit.BasePipelineTest

class TestJavaLibraryPipeline extends BasePipelineTest implements RegressionTest {
    // Some overridden setUp() which loads shared libs
    // and registers methods referenced in javaLib.groovy

    void registerPipelineMethods() {
        ...
        def fileList = [new File("testFile1"), new File("testFile2")]
        helper.registerAllowedMethod('findFiles', { f -> return fileList })
        ...
    }
}

and my javaLib.groovy contains this currently failing part:

    ...
    def pomFiles = findFiles glob: "target/publish/**/${JOB_BASE_NAME}*.pom"
    if (pomFiles.length < 1) { // Fails with java.lang.NullPointerException: Cannot get property 'length' on null object
        error("no pom file found")
    }
    ...

I have tried multiple closures returning various objects, but everytime I get NPE. Question is - how to correctly register "findFiles" method?

N.B. That I'm very new to mocking and closures in groovy.

Chris Maes
  • 35,025
  • 12
  • 111
  • 136
zrks
  • 61
  • 6

3 Answers3

1

Looking at the source code and examples on GitHub, I see a few overloads of the method (here):

  1. void registerAllowedMethod(String name, List<Class> args = [], Closure closure)
  2. void registerAllowedMethod(MethodSignature methodSignature, Closure closure)
  3. void registerAllowedMethod(MethodSignature methodSignature, Function callback)
  4. void registerAllowedMethod(MethodSignature methodSignature, Consumer callback)

It doesn't look like you are registering the right signature with your call. I'm actually surprised you aren't getting a MissingMethodException with your current call pattern.

You need to add the rest of the method signature during registration. The findFiles method is taking a Map of parameters (glob: "target/publish/**/${JOB_BASE_NAME}*.pom" is a map literal in Groovy). One way to register that type would be like this:

helper.registerAllowedMethod('findFiles', [Map.class], { f -> return fileList })
mkobit
  • 43,979
  • 12
  • 156
  • 150
  • Even if I try different signatures I still get NPE. My thinking is that value returned from closure doesn't get passed to findFiles which in turn isn't passed to pomFiles variable resulting in NPE. But due to lack of experience I don't know yet how to troubleshoot it. – zrks Feb 14 '18 at 07:46
  • 1
    I also opened help request on PipelineUnit repository: https://github.com/jenkinsci/JenkinsPipelineUnit/issues/91. But still suggestion mentioned there didn't help. I guess some pointer on how to debug this issue would help too. – zrks Feb 14 '18 at 08:00
  • @zrks were you able to find a solution? I am also facing similar issue. I added void registerDeclarativeMethods() { helper.registerAllowedMethod('inside', [String.class], null) } to my class that extends BasePipelineTest, but I am still getting groovy.lang.MissingMethodException: No signature of method: java.lang.String.inside() is applicable for argument types: (String, com.dsl.shared.WindowService$_createWindow_closure15$_closure25) values: [-u root, com.dsl.shared.WindowService$_createWindow_closure15$_closure25@60bd273d] – Angelina May 20 '20 at 06:08
  • @Angelina yes, here is the solution to my problem - https://github.com/jenkinsci/JenkinsPipelineUnit/issues/91 btw, check what parameter type takes 'inside' method – zrks May 21 '20 at 19:20
1

I also faced the same issue. However, I was able to mock the findFiles() method using the following method signature:

helper.registerAllowedMethod(method('findFiles', Map.class), {map ->
            return [['path':'testPath/test.zip']]
        })
user2125722
  • 1,289
  • 3
  • 18
  • 29
0

So I found a way on how to mock findFiles when I needed length property:

helper.registerAllowedMethod('findFiles', [Map.class], { [length: findFilesLength ?: 1] })

This also allows to change findFilesLength variable in tests to test different conditions in pipeline like the one in my OP.

zrks
  • 61
  • 6