Unit testing Spock执行实际而不是模拟

Unit testing Spock执行实际而不是模拟,unit-testing,groovy,spock,Unit Testing,Groovy,Spock,我在类调用中有以下方法: def call(List artifacts) { String methodName = "deployStream${artifactType.toString()}" for (artifact in artifacts) { "${methodName}"(artifact) } } def deployStreamSOA(Map artifactDetails) { String artifactName

我在类调用中有以下方法:

def call(List artifacts) {
    String methodName = "deployStream${artifactType.toString()}"

    for (artifact in artifacts) {
        "${methodName}"(artifact)
    }
}

def deployStreamSOA(Map artifactDetails) {
    String artifactName = getDownloadArtifactName(artifactDetails)
    String targetName = getDownloadArtifactTarget(artifactDetails)
    String modifiedConfigFileName = getUpdatedConfigFileName(artifactName)
    deployArtifact(artifactName, targetName, modifiedConfigFileName)
}
我试图通过以下测试检查是否调用了deployStreamSOA:

def "type is SOA then deployStreamSOA is called"() {
    setup:
    def artifactList = [[groupId: "com.company", artifactId: "artifact1", version: "1.0.0"]]
    DeployArtifacts deployArtifacts = Spy(DeployArtifacts, constructorArgs: [ArtifactType.SOA]) {
        deployStreamSOA(_ as Map) >> ""
    }

    when:
    "DeployArtifact call is passed the SOA ArtifactType"
    deployArtifacts.call(artifactList)

    then:
    "the deployStreamSOA method is called"
    1 * deployArtifacts.deployStreamSOA(_)
}
但它正在执行实际的deployStreamSOA方法

我认为这可能与动态方法名生成有关,因此我尝试将其更改为普通方法调用,但仍然有相同的响应

如果我也模拟deployStreamSOA方法中的方法,那么它会通过,并返回模拟值

为什么它不是在模仿deployStreamSOA,而是在模仿其他方法


如何在不模拟此调用的所有内部方法的情况下使其工作?

为了修复应用程序代码并使其实际调用预期的方法,请更改

“方法名”(工件)
进入

“$methodName”(工件)

更新:至于调用原始方法而不是stubbed spy方法的实际解释,可以在Spock手册第章中找到解释。这是许多斯波克新手犯的一个错误,甚至一些更有经验的用户可能会偶尔忘记这一点:

相同方法调用的模拟和存根必须在相同的交互中发生

也就是说,您可以这样修复您的测试:

package de.scrum_master.stackoverflow.q57108265
导入spock.lang.Specification
类DeployArtifactsTest扩展了规范{
def“类型为SOA,然后将deployStreamSOA称为”(){
设置:
def artifactList=[[groupId:“com.company”,artifactId:“artifact1”,版本:“1.0.0”]]
DeployArtifacts DeployArtifacts=Spy(constructorArgs:[ArtifactType.SOA])
什么时候:
“部署工件调用传递给SOA工件类型”
deployArtifacts.call(artifactList)
然后:
“已调用deployStreamSOA方法”
1*deployArtifacts.deployStreamSOA(41;>>“”
}
}

为了修复应用程序代码并使其实际调用预期的方法,请更改

“方法名”(工件)
进入

“$methodName”(工件)

更新:至于调用原始方法而不是stubbed spy方法的实际解释,可以在Spock手册第章中找到解释。这是许多斯波克新手犯的一个错误,甚至一些更有经验的用户可能会偶尔忘记这一点:

相同方法调用的模拟和存根必须在相同的交互中发生

也就是说,您可以这样修复您的测试:

package de.scrum_master.stackoverflow.q57108265
导入spock.lang.Specification
类DeployArtifactsTest扩展了规范{
def“类型为SOA,然后将deployStreamSOA称为”(){
设置:
def artifactList=[[groupId:“com.company”,artifactId:“artifact1”,版本:“1.0.0”]]
DeployArtifacts DeployArtifacts=Spy(constructorArgs:[ArtifactType.SOA])
什么时候:
“部署工件调用传递给SOA工件类型”
deployArtifacts.call(artifactList)
然后:
“已调用deployStreamSOA方法”
1*deployArtifacts.deployStreamSOA(41;>>“”
}
}

要求示例代码是完整类(理想情况下是一个完整类)会要求很多吗?作为一个拥有31k声誉的有经验的SO用户,您应该知道如何提问,并使其他人能够轻松回答问题。要求您的示例代码是完整类(理想情况下是一个完整类)会要求很多吗?作为一个拥有31k声誉的有经验的SO用户,你应该知道如何提问,并让其他人轻松回答。a)我认为这不会有什么不同,因为这当然是一个列表,Tim。我更新了我的答案。谢谢你的反馈。第一部分肯定是我在思考代码可能有什么问题时留下的,但实际上还可以。罪魁祸首其实是OP在应用程序代码中的疏忽。我再次更新了答案,为OP的实际问题提供了解决方案。对不起,我很匆忙,完全忘记了。我通常没那么邋遢。我真丢脸!哈哈,每个人都会这样谢谢。作为一个习惯于JUnit并且对Spock完全陌生的人,我没有意识到这一点,并且在文档中遗漏了它。当然,你是对的,我应该提供一个完全有效的例子。下一次我会努力做得更好a)我不认为会有什么不同,因为这当然是一份清单,蒂姆。我更新了我的答案。谢谢你的反馈。第一部分肯定是我在思考代码可能有什么问题时留下的,但实际上还可以。罪魁祸首其实是OP在应用程序代码中的疏忽。我再次更新了答案,为OP的实际问题提供了解决方案。对不起,我很匆忙,完全忘记了。我通常没那么邋遢。我真丢脸!哈哈,每个人都会这样谢谢。作为一个习惯于JUnit并且对Spock完全陌生的人,我没有意识到这一点,并且在文档中遗漏了它。当然,你是对的,我应该提供一个完全有效的例子。下次我会努力做得更好