[我有一个共享库,它调用管道步骤方法(withCredentials)。我试图测试在调用myMethodToTest时使用sh脚本正确调用withCredentials方法,但是在withCredentials闭包中进行迭代时遇到错误:
测试方法
class myClass implements Serializable{
def steps
public myClass(steps) {this.steps = steps}
public void myMethodToTest(script, credentialsId, dataObject) {
dataObject.myKeyValue.each {
steps.withCredentials([[
$class: ‘UsernamePasswordMultiBinding’, credentialsId: "${credentialsId}",
usernameVariable: 'USR', passwordVariable: 'PWD']]) {
steps.sh("git push --set-upstream origin ${it.branch}")
}
}
}
}
模拟
class Steps {
def withCredentials(List args, Closure closure) {}
}
class Script {
public Map env = [:]
}
测试用例
def "testMyMethod"(){
given:
def steps = Spy(Steps)
def script = Mock(Script)
def myClassObj = new myClass(steps)
def myDataObject = [
'myKeyValue' : [['branch' :'mock' ]]
]
when:
def result = myClassObj.myMethodToTest(script, credId, myDataObject)
then:
1 * steps.withCredentials([[
$class: 'UsernamePasswordMultiBinding',
credentialsId: "mycredId",
usernameVariable: 'USR',
passwordVariable: 'PWD'
]])
1 * steps.sh(shString)
where:
credId | shString
"mycredId" | "git push --set-upstream origin mock"
错误(变量在关闭时为空)
java.lang.NullPointerException: Cannot get property 'branch' on null object
您有两个嵌套闭包的情况
dataObject.myKeyValue.each { // <- first closure it references the map
steps.withCredentials([[
$class: ‘UsernamePasswordMultiBinding’, credentialsId: "${credentialsId}",
usernameVariable: 'USR', passwordVariable: 'PWD']]) { // <- second closure it is null as no parameter is passed to this closure
steps.sh("git push --set-upstream origin ${it.branch}")
}
}
要修复它,您应该命名第一个参数
dataObject.myKeyValue.each { conf ->
steps.withCredentials([[
$class: ‘UsernamePasswordMultiBinding’, credentialsId: "${credentialsId}",
usernameVariable: 'USR', passwordVariable: 'PWD']]) {
steps.sh("git push --set-upstream origin ${conf.branch}")
}
}