当前位置: 首页 > 知识库问答 >
问题:

用Groovy模拟Jenkins管道

岳正阳
2023-03-14

我对Jenkins pipeline非常陌生,我正在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类来(尝试)用凭据和用户名密码模拟

测试类是这样的(有点简化):

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()
  }

}

最初我只是调用闭包()来执行代码,但是我得到了错误groovy.lang.MissingProperty tyException:没有这样的属性:MY_USER类:当执行到达pipeline.sh行时,MyClass
所以我试图将测试值注入到MY_USERMY_PASSWORD中,这样它们就可以用for循环来解析。我得到了完全相同的错误,但是这次调用closure.set属性时。我在调试时检查了arg.get('usernameVariable')正确地解析为MY_USER

好吧,我迷路了。我不是一个真正的Groovy专家,所以我可能会错过一些东西。任何关于理解正在发生的事情的帮助都将不胜感激!


共有1个答案

汪胡非
2023-03-14
匿名用户

正如@mkobit在评论中提到的那样,这看起来确实是使用JenkinsPipelineUnit的理想人选,但出于学术兴趣,问题中的样本实际上可以与委托人相关的微小更改一起工作。原始的MyClass中也有一个拼写错误。我的方法应该是MyClass。调用。这是正在工作的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}'"
    }
  }
}

测试应按原样进行。

 类似资料:
  • 我们有重复使用的詹金斯管道和使用相同功能的一些管道。现在我的问题是:重用它们的正确方法是什么。我使用一个共享库,但我不知道我是否必须添加漂亮的脚本或完整的管道?漂亮的脚本似乎是在根中执行的,而不是我的詹金斯工作区,这是一个大问题。你是如何正确处理这件事的?

  • 我目前正在尝试从jenkins管道中的文件加载一个自定义groovy类。我尝试了这里提出的解决方案: 如何在Jenkins管道中导入类文件? 作为... JenkinsPipelineUtilityClass.groovy 詹金斯档案 并尝试同样使用GroovyClassLoader(再次使用上述类) 詹金斯档案 我在这两方面都遇到了同样的错误: 我已经检查了正在进行的脚本批准,里面什么都没有,我

  • 我试图为一个类编写一个单元测试,这个类使用带有库中的的Google vision API。问题是,由于某种原因,我的模拟仍然调用真正的方法,然后抛出一个NPE,这破坏了我的测试。我以前从未在模拟上见过这种行为,我想知道我是不是做错了什么,是不是Spock/Groovy中有bug,还是与Google lib有关?

  • 我正在尝试在我的Jenkins管道中使用groovy-postbuild-plugin,我可以让它显示纯文本,但我不能使用它的参数。 所以这是有效的: 但是这个没有: 这是我得到的错误:

  • 根据Andrew Bayer的说法,您不应该向其他人注入声明性管道。将来可能会有人支持它,但可能不会。 我目前正在尝试在管道中启动一个管道,但我想知道我需要做什么才能使它工作。jenkins网页上的文档说明,如果新作业或管道与第一个作业或管道位于同一文件夹中,则可以从直接名称或绝对路径调用它。我已经尝试了所有不同的方法,目前我正在尝试一个文件的绝对路径,我刚刚检查过它一秒钟前存在,但它说它不存在。

  • 我正在构建一个jenkins管道,作业可以由远程触发。我需要知道哪个IP触发了作业。所以我有一个小Groovy脚本,它返回远程IP。使用EnvInject-plugin,我可以轻松地在正常的自由式作业中使用这个变量,但是我如何在管道中使用它?我不能将EnvInject-plugin与管道插件一起使用:( 这是获取IP的小脚本: