Spock:模拟类的方法不匹配 [英] Spock: mocked class's method is not being matched

查看:102
本文介绍了Spock:模拟类的方法不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够为我的代码的精简版通过测试(感谢cgrim!

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

推荐答案

您–像以前一样,遇到了Spock的一个巨大陷阱:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆