我的代码的精简版本能够通过测试(感谢 cgrim!Spock: method not recognized as an invocation),但是使用真正的代码它不会工作,除非 getAssetIdBatch
返回非空的东西。我不明白为什么我的互动没有被实现。下面,您可以看到三次尝试获取 getAssetIdBatch
以返回 map1
示例。
这是代码的简化版本:
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
。设置交互我做错了什么?
Using logging directory: './logs'
Using log file prefix: ''
test
batch: null
最佳答案
你——就像之前的许多人一样——遇到了 Spock 的一个巨大陷阱:combination of Mocking and Stubbing以及它必须在一条线上发生的事实。形成文档:
Mocking and stubbing of the same method call has to happen in the same interaction.
您在 given
block 中添加了 assetServiceClient.getAssetIdBatch
以返回 map1
,然后您在 then< 中验证了模拟调用
block 。后者隐含地指示模拟返回 null
而不是 map1
。思考
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) // >> null
将该行更改为
1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) >> map1
并在该方法的范围内定义 map1
,它将按预期工作。
您可能还想从 given
block 中删除重复项。
不要担心它在 then
block 中。 Spock 在您进入 when
block 之前执行所有模拟和 stub 。如果您想查看代码,请逐步执行。
关于groovy - Spock:模拟类方法不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53267791/