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

如何Mock Jenkins共享库vars文件内自定义步骤的本地方法进行单元测试

Jenkins共享库同文件本地方法单元测试Mock方案

问题根因

Jenkins Pipeline Unit(JPU)的helper.registerAllowedMethod仅适用于全局DSL方法的Mock,同脚本内的本地方法调用属于Groovy类内部的直接方法调度,不会走JPU的DSL方法拦截逻辑,因此常规的注册方案无法生效,你观察到的类似「内联」的堆栈表现就是该机制导致的。

可行方案:Groovy元编程动态替换方法

直接对loadScript返回的脚本实例的元类进行修改,覆盖目标方法即可实现Mock,无需引入额外框架,也不需要修改原有共享库代码,示例如下:

// test/com/myOrg/stepTest.groovy
import org.junit.*
import com.lesfurets.jenkins.unit.*
import com.lesfurets.jenkins.unit.BasePipelineTest
import static groovy.test.GroovyAssert.*

class stepTest extends BasePipelineTest {
  def step
  // 保存原方法引用,用于测试后恢复
  def originalMethod2

  @Before
  void setUp() {
    super.setUp()
    step = loadScript("vars/step.groovy")
    originalMethod2 = step.&method2
  }

  @After
  void tearDown() {
    // 恢复原方法,避免测试用例之间互相影响
    step.metaClass.method2 = originalMethod2
  }

  @Test
  void method1Test_true () {
    // Mock method2,固定返回true,参数要和原方法匹配
    step.metaClass.method2 = { def value -> true }

    step.method1()

    // 断言echo调用的内容
    assert helper.callStack.find { it.methodName == 'echo' }?.args?.get(0) == 'ok'
  }

  @Test
  void method1Test_false () {
    // Mock method2,固定返回false
    step.metaClass.method2 = { def value -> false }

    step.method1()

    assert helper.callStack.find { it.methodName == 'echo' }?.args?.get(0) == 'no'
  }
}

注意事项

  • 方法签名要完全匹配:Mock的闭包参数数量、顺序要和原方法一致,否则会触发Groovy方法签名匹配失败,调用到原方法
  • 如果不需要保留原方法,也可以省略@Before和@After里的保存恢复逻辑,直接在每个测试用例里覆盖目标方法即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:15:07