You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JenkinsPipelineUnit中正确注册findFiles方法?

如何在Jenkins Pipeline Unit中正确注册findFiles步骤并避免空指针异常(NPE)

刚接触Groovy Mocking和Jenkins Pipeline Unit时碰到这种问题太正常了,我来帮你梳理下正确的注册方式,解决NPE的困扰。

首先要明确:Jenkins的findFiles步骤实际返回的是FileWrapper类型的数组,Pipeline代码里通常会遍历这个数组并访问文件的属性(比如name、path),如果Mock返回的对象没有模拟这些属性,就很容易触发NPE。

正确的Mock注册步骤

  1. 确保测试类继承BasePipelineTest
    先在你的TestJavaApp.groovy里做好基础初始化,确保能拿到Jenkins Pipeline Unit提供的helper对象:

    import com.lesfurets.jenkins.unit.BasePipelineTest
    
    class TestJavaApp extends BasePipelineTest {
        @Override
        void setUp() throws Exception {
            super.setUp()
            // 在这里注册findFiles的Mock实现
            registerFindFilesMock()
        }
    }
    
  2. 注册模拟的findFiles方法
    用helper.registerAllowedMethod来注册,关键是要返回模拟了FileWrapper属性的对象数组,这里用Groovy的Expando(可以动态添加属性的类)来模拟最方便:

    private void registerFindFilesMock() {
        helper.registerAllowedMethod('findFiles', [Map.class], { Map params ->
            // 根据你的业务场景,模拟返回对应的文件列表
            def mockFiles = [
                new Expando(name: 'app.jar', path: './target/app.jar'),
                new Expando(name: 'test-report.html', path: './build/reports/test-report.html')
            ]
            // 转成数组,匹配findFiles实际返回的类型
            return mockFiles as Object[]
        })
    }
    

为什么之前会触发NPE?

大概率是这两个原因:

  • 返回的对象没有模拟Pipeline代码中用到的属性:比如你的javaLib.groovy里遍历findFiles结果时,会访问file.name或file.path,如果Mock返回的是普通Map/List,用.访问属性就会报错。
  • 返回的不是数组类型:findFiles实际返回的是FileWrapper[],如果返回List,某些场景下会因为类型不匹配引发异常。

进阶:根据参数返回不同结果

如果你的javaLib.groovy里调用findFiles时传了不同的glob参数,还可以在Mock闭包里根据参数动态返回结果:

private void registerFindFilesMock() {
    helper.registerAllowedMethod('findFiles', [Map.class], { Map params ->
        if (params.glob == '**/*.jar') {
            return [new Expando(name: 'app.jar', path: './target/app.jar')] as Object[]
        } else if (params.glob == '**/*.html') {
            return [new Expando(name: 'test-report.html', path: './build/reports/test-report.html')] as Object[]
        }
        // 默认返回空数组
        return [] as Object[]
    })
}

测试验证示例

在TestJavaApp.groovy里可以验证findFiles的调用情况:

void testFindFilesInJavaLib() {
    def script = loadScript('javaLib.groovy')
    script.yourMethodThatUsesFindFiles()
    // 验证findFiles是否按预期参数被调用
    verifyCall('findFiles', [glob: '**/*.jar'])
}

内容的提问来源于stack exchange,提问作者zrks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:09:04