Spock:模拟类的方法不匹配 [英] Spock: mocked class's method is not being matched
问题描述
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.
这是代码的精简版:
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
}
}
现在是测试:
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)
}
}
运行此命令后,可以看出该批次仍在打印为null
.设置交互功能时我做错了什么?
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.
在given
块中对assetServiceClient.getAssetIdBatch
进行存根返回map1
,然后在then
块中验证了模拟调用.后者隐式指示该模拟返回null
而不是map1
.想想
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
将该行更改为
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) >> map1
并在方法的范围内定义map1
,它将按预期工作.
and define map1
in the method's scope and it will work as expected.
您可能还希望从given
块中删除重复项.
You probably want to remove the duplicate from the given
block as well.
不用担心这会出现在then
块中.在进入when
块之前,Spock将执行所有模拟和存根操作.如果您想查看它,请单步执行代码.
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.
这篇关于Spock:模拟类的方法不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!