1

我正在尝试使用 Groovy 中的 Spock 测试具有 Arrow-kt 类型的 Kotlin 代码。但是,我无法使用 Arrow-kt 的附加功能,例如Some. 例如,我有一个测试如下:

    @Unroll
    def "add returns #expected for queryRecord #queryRecord"() {
        given:
        def ip = "ip"
        def rule = "rule"

        when:
        def result = unit.add(ip, rule)

        then:
        1 * dynamoDBMapperMock.load(ActionRecord.class, ip) >> queryRecord

        result == expected

        where:
        queryRecord        | expected
        new ActionRecord() | None.INSTANCE
        null               | Some(new ActionInternal("ip"))
    }

虽然第一个数据行成功没有问题,但第二个数据行失败并出现以下错误:

groovy.lang.MissingMethodException: No signature of method: package.name.EventSpec.Some() is applicable for argument types: (package.name.ActionInternal) values: [ActionInternal(dropletIp=null)] Possible solutions: Mock(), Spy(), Stub(), dump(), Mock(groovy.lang.Closure), Mock(java.lang.Class)

我也试过.some()了,但没有用。显然,Groovy 无法访问 Kotlin 扩展,而Some只是一个数据类[ 1 ],所以我不确定为什么我不能在 Groovy 中使用它。

4

1 回答 1

1

是的,您可以在中使用箭头数据类型Groovy,结果不如Kotlincompanion object

例子

import arrow.core.Option
import static arrow.core.OptionKt.getOrElse

static main(args){
    println 'What is your name?'
    def name = Option.@Companion.fromNullable(System.in.newReader().readLine())
        .filterNot { it.isEmpty() }
        .map { it.toUpperCase() }

    println("Welcome ${getOrElse(name) { 'Anonymous' }}")
}

输出

'Welcome JOHN' (or 'Welcome Anonymous' if the provided name is null or empty) 

如您所见,为了能够使用getOrElse扩展功能,我们需要将其作为静态方法导入

暗示

Some除非您绝对确定该值不是,否则不要直接使用null,否则,您应该依靠Option.fromNullable安全地将值提升到Option上下文(即创建SomeNone取决于值是否null存在)

于 2019-01-15T06:10:24.180 回答