groovy - Spock:模拟类方法不匹配

标签 groovy spock

我的代码的精简版本能够通过测试(感谢 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/

相关文章:

groovy - GroovyTestCase 方法必须返回 void 吗?

grails - 带有Geb/Spock的Grails:Grails不会占用我的baseUrl

java - 是否可以覆盖对注入(inject)器的调用?

grails - 从 Maven 原型(prototype)创建 grails 项目

gradle - groovy/gradle用于文件收集过滤器和迭代的正确语法是什么?

java - Groovy 依赖注入(inject)

grails - Grails 2.2应该使用什么Spock,Geb和Selenium版本?

loops - Groovy spock where block 循环 n 次

spring - 如何在 Grails Spock 单元测试中初始化/连接 bean?

arrays - 数组长度的 Jsonpath