使用Spock与jenkins-spock模拟Jenkins内部函数时toComputer返回null
问题根因
- 你使用Spock原生
Mock()创建的Node、Computer实例和jenkins-spock的全局Mock机制冲突。JenkinsPipelineSpecification会自动为所有Jenkins API类生成全局代理Mock,你给原生Mock实例设置的stub规则会被框架的全局拦截器覆盖,导致调用toComputer()时返回框架默认的null值。 - 如果你后续要测试实际业务代码,还漏掉了
Jenkins.getInstanceOrNull()的stub规则,业务代码调用该方法时会直接返回null。
修复方案
修改后的完整测试代码如下:
import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification import hudson.model.Computer import hudson.model.Node import jenkins.model.Jenkins class MaintenanceSpec extends JenkinsPipelineSpecification { def 'Script does not fail or throw exceptions'() { given: // 所有Jenkins相关类的Mock都通过jenkins-spock提供的getPipelineMock创建 Computer computer = getPipelineMock(Computer.class.getName()) Node node = getPipelineMock(Node.class.getName()) // 显式stub toComputer方法的返回值 node.toComputer() >> computer Jenkins jenkins = getPipelineMock(Jenkins.class.getName()) // stub 静态方法getInstanceOrNull返回你创建的Jenkins Mock实例 getPipelineMock('Jenkins.getInstanceOrNull') >> jenkins jenkins.getNode('Node 1') >> node when: System.out.println(jenkins.getNode('Node 1').toString()) System.out.println(computer.toString()) System.out.println(jenkins.getNode('Node 1').toComputer().toString()) System.out.println(node.toComputer().toString()) then: // 可选:显式声明交互规则,确认toComputer被调用且返回指定值 2 * node.toComputer() >> computer noExceptionThrown() } }
补充说明
- 如果你习惯用Spock原生Mock的写法,可以把方法stub规则统一放到
then块中声明,优先级会高于jenkins-spock的默认规则 - 测试实际业务的
disconnectNode方法时,还要记得补充setTemporarilyOffline方法的stub规则,避免调用报错
内容的提问来源于stack exchange,提问作者Pablo Garcia Bastante
相关产品推荐
相关产品推荐

