本文介绍了使用Spock的Groovy共享库测试管道步骤方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个共享库,该库调用管道步骤方法(withCredentials).我正在尝试测试withCredentails方法在调用myMethodToTest时是否已通过sh脚本正确调用,但遇到错误:
I have shared library that calls pipeline step method(withCredentials).I am trying to test withCredentails method is being called correctly with sh scripts on calling myMethodToTest but facing error:
class myClass implements Serializable{
def steps
public myClass(steps) {this.steps = steps}
public void myMethodToTest(script, String credentialsId) {
steps.withCredentials([[$class: ‘UsernamePasswordMultiBinding’, credentialsId: "${credentialsId}", usernameVariable: ‘USR’, passwordVariable: ‘PWD’]]) {
steps.sh """
export USR=${script.USR}
export PWD=${script.PWD}
$mvn -X clean deploy
"""
}
}
}
//模拟
class Steps {
def withCredentials(List args, Closure closure) {}
}
class Script {
public Map env = [:]
}
//测试用例
def "testMyMethod"(){
given:
def steps = Mock(Steps)
def script = Mock(Script)
def myClassObj = new myClass(steps)
script.env['USR'] = "test-user"
when:
def result = myClassObj.myMethodToTest(script, credId)
then:
1 * steps.withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: "mycredId", usernameVariable: 'USR', passwordVariable: 'PWD']])
1 * steps.sh(shString)
where:
credId | shString
"mycredId" | "export USR='test-user'"
//错误
Too few invocations for:
1 * steps.withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: "mycredId", usernameVariable: ‘USR’, passwordVariable: ‘PWD’]]) (0 invocations)
Unmatched invocations (ordered by similarity):
1 * steps.withCredentials([['$class':'UsernamePasswordMultiBinding', 'credentialsId':mycredId, 'usernameVariable’:’USR’, 'passwordVariable':'PWD’]]
推荐答案
在测试和应用程序类的代码中,您都有一堆细微而不是细微的错误.因此,让我提供一个新的 MCVE ,我在其中修复了所有内容并评论了测试中的一些关键部分:
You have a whole bunch of subtle and not so subtle errors in your code, both test and application classes. So let me provide a new MCVE in which I fixed everything and commented a few crucial parts inside the test:
package de.scrum_master.stackoverflow.q59442086
class Script {
public Map env = [:]
}
package de.scrum_master.stackoverflow.q59442086
class Steps {
def withCredentials(List args, Closure closure) {
println "withCredentials: $args, " + closure
closure()
}
def sh(String script) {
println "sh: $script"
}
}
package de.scrum_master.stackoverflow.q59442086
class MyClass implements Serializable {
Steps steps
String mvn = "/my/path/mvn"
MyClass(steps) {
this.steps = steps
}
void myMethodToTest(script, String credentialsId) {
steps.withCredentials(
[
[
class: "UsernamePasswordMultiBinding",
credentialsId: "$credentialsId",
usernameVariable: "USR",
passwordVariable: "PWD"]
]
) {
steps.sh """
export USR=${script.env["USR"]}
export PWD=${script.env["PWD"]}
$mvn -X clean deploy
""".stripIndent()
}
}
}
package de.scrum_master.stackoverflow.q59442086
import spock.lang.Specification
class MyClassTest extends Specification {
def "testMyMethod"() {
given:
// Cannot use mock here because mock would have 'env' set to null. Furthermore,
// we want to test the side effect of 'steps.sh()' being called from within the
// closure, which also would not work with a mock. Thus, we need a spy.
def steps = Spy(Steps)
def myClass = new MyClass(steps)
def script = new Script()
script.env['USR'] = "test-user"
when:
myClass.myMethodToTest(script, credId)
then:
1 * steps.withCredentials(
[
[
class: 'UsernamePasswordMultiBinding',
credentialsId: credId,
usernameVariable: 'USR',
passwordVariable: 'PWD'
]
],
_ // Don't forget the closure parameter!
)
// Here we need to test for a substring via argument constraint
1 * steps.sh({ it.contains(shString) })
where:
credId | shString
"mycredId" | "export USR=test-user"
}
}
这篇关于使用Spock的Groovy共享库测试管道步骤方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!