Spock错误groovy.lang.MissingMethodException:当一个方法调用另一个方法时

时间:2016-02-06 23:22:00

标签: grails testing groovy spock

当运行单元测试时,当测试的方法调用被测对象内的另一个方法时,我收到有关spoc闭包失败的错误。

错误是:

groovy.lang.MissingMethodException: No signature of method: com.mypackage.RuleRunnerServiceSpec$__spock_feature_0_9_closure12.doCall() is applicable for argument types: ([B, java.lang.Integer, java.lang.Integer) values: [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...], ...]
Possible solutions: call(), doCall(java.io.InputStream), findAll()
    at com.mypackage.RuleRunnerService.loadRulesFromS3(RuleRunnerService.groovy:132)
    at com.mypackage.RuleRunnerServiceSpec.should load from s3(RuleRunnerServiceSpec.groovy:272)

测试是:

void "should load from s3"(){

        given:
            RuleRunnerService ruleService = RuleRunnerService.instance
            ruleService.grailsApplication = [
                    config: [
                            alert: [
                                    engine: [s3 : [bucketName: 'bucket']]
                            ]
                    ]
            ]
            def s3wrapper = mockFor(S3Wrapper, true)

            s3wrapper.demand.asBoolean(0..999) { -> true }
            s3wrapper.demand.getS3ObjectToInputStream(0..999){
               InputStream stream -> new FileInputStream('test/resources/samples-drl/samplefile.drl')
            }

            ruleService.s3 = s3wrapper.createMock()
        when:
            ruleService.loadRulesFromS3('test')
        then:
            ruleService.hasRulePackageByName('test')

正在测试的方法是:

void loadRulesFromS3(String organizationId){

        String bucketName = grailsApplication.config.alert.engine.s3.bucketName


        S3Wrapper s3 = getS3Wrapper()
        InputStream newRules = s3.getS3ObjectToInputStream(bucketName, organizationId)

        loadRulesFromString(organizationId, [newRules.text])
    }

调用以loadRulesFromString(...)调用上面的错误退出。是否需要一些设置才能在Spock测试中进行内部方法调用?

1 个答案:

答案 0 :(得分:0)

我们无法看到您测试的其余背景,但可能是这样的:

import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(RuleRunnerService)
class RuleRunnerServiceSpec extends Specification {

    def "shouldLoadFromS3"() {
        given:
            grailsApplication.config.alert.engine.s3.bucketName = 'bucket'
            def s3WrapperMock = mockFor(S3Wrapper, true)
            s3WrapperMock.demand.with {
                asBoolean(0..99) { -> true }
                getS3ObjectToInputStream(0..999) { InputStream stream -> 
                    new FileInputStream('test/resources/samples-drl/samplefile.drl')
                }
            }
            service.s3 = s3WrapperMock.createMock()
        when:
            service.loadRulesFromS3('test')
        then:
            service.hasRulePackageByName('test')
    }
}

或接近这一点(禁止拼写错误)。我一直在Spock规范中使用Groovy模拟。

理想情况下,loadRulesFromS3的单元测试会将该方法作为测试中唯一的“变量”。使用hasRulePackageByName(我假设是服务中的另一种方法)来确定loadRulesFromS3的有效性在技术上是在测试中引入另一个变量。如果hasRulePackageByName方法中存在错误,则loadRulesFromS3的此测试可能会失败。这种风险是否是重要的取决于你。