Kotlin 运行Jacoco覆盖时缺少带有when和enum的分支

Kotlin 运行Jacoco覆盖时缺少带有when和enum的分支,kotlin,jacoco,Kotlin,Jacoco,我使用jacoco0.8.6,我有一个带有3个值的枚举。 我在下图中显示了这个,我对每个分支都进行了测试,但是Jacoco仍然说我缺少一个分支,而且我的var是非空的。怎么了? JaCoCo执行字节码分析。对于示例.kt object Example { var type: Type = Type.SETUP_LOGIN set(value) { field = value when (value) {

我使用jacoco0.8.6,我有一个带有3个值的枚举。 我在下图中显示了这个
,我对每个分支都进行了测试,但是Jacoco仍然说我缺少一个分支,而且我的
var
是非空的。怎么了?


JaCoCo执行字节码分析。对于
示例.kt

object Example {
    var type: Type = Type.SETUP_LOGIN
        set(value) {
            field = value
            when (value) {
                Type.SETUP_LOGIN -> nop()
                Type.CHANGE_PIN -> nop()
                Type.CHANGE_FINGERPRINT -> nop()
            }
        }

    fun nop() {
    }

    enum class Type {
        SETUP_LOGIN, CHANGE_PIN, CHANGE_FINGERPRINT
    }
}
编者

kotlinc-1.4.30/bin/kotlinc Example.kt
执行

java -v -p Example.class
显示
setType
方法的以下字节码

public final void setType(Example$Type);
    descriptor: (LExample$Type;)V
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=2, locals=2, args_size=2
         0: aload_1
         1: ldc           #17                 // String value
         3: invokestatic  #23                 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
         6: aload_1
         7: putstatic     #11                 // Field type:LExample$Type;
        10: aload_1
        11: getstatic     #29                 // Field Example$WhenMappings.$EnumSwitchMapping$0:[I
        14: swap
        15: invokevirtual #35                 // Method Example$Type.ordinal:()I
        18: iaload
        19: tableswitch   { // 1 to 3
                       1: 44
                       2: 51
                       3: 58
                 default: 65
            }
        44: aload_0
        45: invokevirtual #39                 // Method nop:()V
        48: goto          65
        51: aload_0
        52: invokevirtual #39                 // Method nop:()V
        55: goto          65
        58: aload_0
        59: invokevirtual #39                 // Method nop:()V
        62: goto          65
        65: return
      LineNumberTable:
        line 4: 6
        line 5: 10
        line 6: 44
        line 7: 51
        line 8: 58
        line 9: 65
        line 10: 65
如您所见,
tableswitch
有4个分支,这正是您在JaCoCo报告中看到的


仅查看此类字节码(就像JaCoCo所做的那样),无法意识到无法访问
tableswitch
default
分支-在不更改任何其他内容的情况下,向enum再添加一个值,重新编译,您将看到与此
setType
方法完全相同的字节码。

您可以使用
穷举

val <T> T.exhaustive: T
get() = this

非常感谢。是的,我用一个else替换了最后一个分支,它可以工作了
when (value) {
    Type.SETUP_LOGIN -> nop()
    Type.CHANGE_PIN -> nop()
    Type.CHANGE_FINGERPRINT -> nop()
}.exhaustive