Spock:模拟类的方法不匹配

Mat*_*kao 3 groovy spock

我能够对我的代码的简化版本进行通过测试(感谢 cgrim!Spock:方法未被识别为调用),但是对于真正的代码,除非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

    }
}
Run Code Online (Sandbox Code Playgroud)

现在测试:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

运行时,可以看到批次仍在打印为null. 我在设置交互时做错了什么?

Using logging directory: './logs'
Using log file prefix: ''
test
batch: null
Run Code Online (Sandbox Code Playgroud)

Mic*_*ael 6

你——和之前的很多人一样——遇到了 Spock 的一个巨大陷阱:Mocking 和 Stubbing组合以及它必须在一行中发生的事实。形成文档:

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

您在块中存根assetServiceClient.getAssetIdBatch返回map1given然后验证了then块中的模拟调用。后一个隐式指示模拟返回null而不是map1. 思考

1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) // >> null
Run Code Online (Sandbox Code Playgroud)

将该行更改为

1 * assetServiceClient.getAssetIdBatch(_ as String, _ as String, _, _ as Map) >> map1
Run Code Online (Sandbox Code Playgroud)

map1在方法的范围内定义,它将按预期工作。

您可能还想从given块中删除重复项。

不要担心这在then块中。Spock 在您进入when块之前执行所有模拟和存根。如果您想查看代码,请单步执行。