I was able to get a passing test for the dumbed down version of my code (thanks to cgrim! Spock: method not recognized as an invocation), but with the real code it won't work unless the getAssetIdBatch
returns something that is non-null. I can't figure out why my interactions aren't being implemented. Below, you can see three attempts to get getAssetIdBatch
to return the map1
sample.
Here's a dumbed down version of the code:
class VmExportTaskSplitter implements TaskSplitter<Export> {
@Inject
AssetServiceClient assetServiceClient
@Override
int splitAndSend(Export export) {
Map batch = [:]
Map tags = [:]
if (true) {
println('test')
batch = assetServiceClient.getAssetIdBatch(export.containerUuid,
export.userUuid, (String) batch.scrollId, tags)
print('batch: ')
println(batch)
}
return 1
}
}
And now the test:
class VmExportTaskSplitterSpecification extends Specification{
def "tags should be parsed correctly"(){
setup:
Export export = new Export(containerUuid: "000", userUuid: "000", chunkSize: 10)
FilterSet filterSet = new FilterSet()
filterSet.tag = [:]
filterSet.tag['tag.Location'] = 'Boston'
filterSet.tag['tag.Color'] = 'red'
Map<String, String> expectedTags = ['tag.Location':'Boston', 'tag.Color':'red']
ObjectMapper mapper = new ObjectMapper()
export.filters = mapper.writeValueAsString(filterSet)
def assetServiceClient = Mock(AssetServiceClientImpl) {
Map map1 = [assetIds:["1","2","3","4","5"],scrollId:null]
getAssetIdBatch(_ as String,_ as String, null, _ as Map) >> map1
getAssetIdBatch('000', '000', null, ['tag.Location':'Boston', 'tag.Color':'red']) >> map1
getAssetIdBatch(_, _, _, _) >> map1
}
VmExportTaskSplitter splitter = new VmExportTaskSplitter()
splitter.assetServiceClient = assetServiceClient
when:
splitter.splitAndSend(export)
then:
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map)
}
}
When this is run it can be seen that batch is still being printed as null
. What am I doing wrong with setting up the interactions?
Using logging directory: './logs'
Using log file prefix: ''
test
batch: null
You –like so many before– ran into the one giant gotcha of Spock: the combination of Mocking and Stubbing and the fact that it has to happen in one line. Form the docs:
Mocking and stubbing of the same method call has to happen in the same interaction.
You stubbed assetServiceClient.getAssetIdBatch
to return map1
in your given
block and then you verified the mocked call in your then
block. The latter one implicitly instructs the mock to return null
instead of map1
. Think
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) // >> null
Change that line to
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) >> map1
and define map1
in the method's scope and it will work as expected.
You probably want to remove the duplicate from the given
block as well.
Don't worry about this being in the then
block. Spock executes all mocking and stubbing before you enter the when
block. Step through the code if you'd like to see it.