模拟 jenkins vars 文件中的自定义步骤

Max*_*one 6 junit mocking jenkins jenkins-pipeline-unit

在我的 Jenkins 共享库中,/vars 目录中有大量定义自定义步骤的 groovy 文件。

其中许多都定义了多个方法,文件中的一个方法可能会调用同一文件中的另一个方法。

我正在寻找一种方法来模拟这些本地方法,这样我就可以对每个方法进行单元测试,特别是那些调用其他方法的方法,而无需实际调用它们。

说结构是这样的:

// vars/step.groovy

def method1() {
  def someVar
  
  result = method2(someVar)

  if (result) { 
    echo 'ok' 
  }
  else { 
    echo 'no' 
  }

}

def method2(value) {

  if (value == 1) { 
    return true 
  }
  else { 
    return false 
  }

}

Run Code Online (Sandbox Code Playgroud)

显然这是一个非常简单的例子。但我需要的是一种模拟方法,method2以便我可以使用 和 进行测试method1resulttrue无需false实际调用method2

我已经尝试过该helper.registerAllowedMethod模式,但这似乎不适用于本地方法。我尝试过 Mockito 和 Spock,但它们对于我的需求来说似乎太过分了,而且对于简单的情况需要注入太多的改变。我还尝试使用模拟闭包在测试脚本中本地定义方法,但我找不到执行此操作的正确位置和/或正确的语法。

我希望有一种方法可以做这样的事情:

// 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

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

  @Test
  void method1Test_true () {
    helper.registerAllowedMethod('method2', [], { true }

    result = step.method1()

    assert 'ok' == result
  }

  @Test
  void method1Test_false () {
    helper.registerAllowedMethod('method2', [], { false }

    result = step.method1()

    assert 'no' == result
  }
}
Run Code Online (Sandbox Code Playgroud)

更新:我最近注意到的一件事是,在堆栈跟踪中,method2本地函数没有列出。就好像本地函数被“内联”实例化,或者以某种方式它实际上不是一个新调用,执行只是流入其中。我不知道技术术语。但这解释了为什么模拟method2永远不会被击中:它永远不会被调用。

 method1.call()
      method1.successfullyMockedExternalFunction()
      // i would expect method2 to be here, but it's not - the next stack items are functions _inside_ method2.
      method1.functionInsideMethod2()
Run Code Online (Sandbox Code Playgroud)

更新 2: 这在 JPU GitHub 存储库中引起了一些关注。