簡體   English   中英

使用Groovy進行Jenkins管道模擬

[英]Jenkins pipeline mocking with Groovy

我對Jenkins管道技術還很陌生,並且正在Groovy中構建一個小型共享庫。
在這種情況下,我試圖提出一些單元測試,然后我必須模擬管道對象。

基本上,我有一個Groovy類,其中包含一個使用憑證執行某些操作的方法:

class MyClass implements Serializable {

  def pipeline

  MyClass(def pipeline) {
    this.pipeline = pipeline
  }

  void my method(String version) {
    pipeline.withCredentials([pipeline.usernamePassword(credentialsId: 'MY_ID', usernameVariable: 'MY_USER', passwordVariable: 'MY_PASSWORD')]) {
        pipeline.sh "./release.sh complete --username ${MY_USER} --password ${MY_PASSWORD} --version '${version}'"
    }
  }
}

因此,當涉及到對該方法進行單元測試時,我創建了PipelineMock Groovy類來(模擬) withCredentialsusernamePassword

測試類是這樣的(有點簡化):

class MyClassTest {

  @Test
  void callWithWithVersionShouldCallCommad() {
    def pipelineMock = new PipelineMock()
    def myClass = new MyClass(pipelineMock)
    myClass('1.0.1')
    assertTrue(pipelineMock.commandCalled.startsWith('./release.sh complete'))
  }

}

我想出的PipelineMock是:

class PipelineMock {

  String commandCalled

  def sh(String command) {
    commandCalled = command
  }

  def usernamePassword(Map inputs) {
    inputs
  }

  def withCredentials(List args, Closure closure) {
    for (arg in args) {
        closure.setProperty(arg.get('usernameVariable'), 'the_login')
        closure.setProperty(arg.get('passwordVariable'), 'the_password')
    }
    closure()
  }

}

最初,我只是調用closure()來執行代碼,但是當執行到達pipeline.sh行時,出現錯誤groovy.lang.MissingPropertyException: No such property: MY_USER for class: MyClass
因此,我嘗試將測試值注入MY_USERMY_PASSWORD以便可以使用for循環對其進行解析。 我遇到了完全相同的錯誤,但這一次是在調用closure.setProperty 我在調試時檢查了arg.get('usernameVariable')正確解析為MY_USER

好吧,我迷路了。 我並不是真正的Groovy專家,所以我可能會錯過一些東西。 任何了解正在發生的事情的幫助將不勝感激!

這看起來確實是使用JenkinsPipelineUnit作為注釋中提到的@mkobit的理想候選人,但是出於學術興趣,問題中的示例實際上將在與委托人相關的微小變化下工作。 原始MyClass.my method還存在一個錯字,我認為應該是MyClass.call 這是工作中的PipelineMock

class PipelineMock {

  String commandCalled

  def sh(String command) {
    commandCalled = command
  }

  def usernamePassword(Map inputs) {
    inputs
  }

  def withCredentials(List args, Closure closure) {
    def delegate = [:]
    for (arg in args) {
        delegate[arg.get('usernameVariable')] = 'the_login'
        delegate[arg.get('passwordVariable')] = 'the_password'
    }
    closure.delegate = delegate
    closure()
  }

}

這是沒有錯字的MyClass

class MyClass implements Serializable {

  def pipeline

  MyClass(def pipeline) {
    this.pipeline = pipeline
  }

  void call(String version) {
    pipeline.withCredentials([pipeline.usernamePassword(credentialsId: 'MY_ID', usernameVariable: 'MY_USER', passwordVariable: 'MY_PASSWORD')]) {
        pipeline.sh "echo ./release.sh complete --username ${MY_USER} --password ${MY_PASSWORD} --version '${version}'"
    }
  }
}

該測試應該可以正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM