Reputation: 46924
I have the following methods in a class call DeployArtifacts:
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)
}
I am trying to check that deployStreamSOA is called with the following test:
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(_)
}
But it is executing the actual deployStreamSOA method.
I thought that it may be to do with the dynamic method name generation, so I tried changing it to a normal method call, but still had the same response.
If I mock the methods inside deployStreamSOA method as well, then it passes, with it returning the mock values.
Why is it not mocking deployStreamSOA, but mocking the other methods?
How do I get this working without mocking all the internal methods this calls?
Upvotes: 0
Views: 84
Reputation: 67477
In order to fix your application code and make it actually call the expected method, please change
"methodName"(artifact)
into
"$methodName"(artifact)
Update: As for the actual explanation why your original method is called and not the stubbed spy method, the explanation can be found in the Spock manual, chapter Combining Mocking and Stubbing. It is a mistake many Spock newbies make and even some more experienced users might forget about it once in a while:
Mocking and stubbing of the same method call has to happen in the same interaction.
I.e. you can fix your test like this:
package de.scrum_master.stackoverflow.q57108265
import spock.lang.Specification
class DeployArtifactsTest extends Specification {
def "type is SOA then deployStreamSOA is called"() {
setup:
def artifactList = [[groupId: "com.company", artifactId: "artifact1", version: "1.0.0"]]
DeployArtifacts deployArtifacts = Spy(constructorArgs: [ArtifactType.SOA])
when:
"DeployArtifact call is passed the SOA ArtifactType"
deployArtifacts.call(artifactList)
then:
"the deployStreamSOA method is called"
1 * deployArtifacts.deployStreamSOA(_) >> ""
}
}
Upvotes: 2