Java Jacoco抱怨不太可能缺少分支机构的覆盖范围

Java Jacoco抱怨不太可能缺少分支机构的覆盖范围,java,kotlin,jacoco,Java,Kotlin,Jacoco,我正在使用Gradle6.3和Jacoco来编译、测试和显示覆盖率报告。但我不明白为什么它会抱怨“2个分支中有1个遗漏”,根本没有分支: 以下是完整的Kotlin数据类: 数据类ListNode(变量值:T,变量下一步:ListNode?){ 重写fun hashCode():Int=value.hashCode() } 如果幕后有分支,它们是什么?我如何覆盖它们?Kotlin中的数据类有默认的自动生成方法(等于,toString,hashCode,getter,setter)。在本例中,我

我正在使用Gradle6.3和Jacoco来编译、测试和显示覆盖率报告。但我不明白为什么它会抱怨“2个分支中有1个遗漏”,根本没有分支:

以下是完整的Kotlin数据类:

数据类ListNode(变量值:T,变量下一步:ListNode?){
重写fun hashCode():Int=value.hashCode()
}

如果幕后有分支,它们是什么?我如何覆盖它们?

Kotlin中的
数据类有默认的自动生成方法(
等于
toString
hashCode
,getter,setter)。在本例中,我们讨论的是
等于
。它在
类ListNode
的代码中不可见,但其JVM字节码肯定包含
equals
toString

Jacoco主要针对JavaCodeCo平均值,因此这种情况可能被视为Jacoco在Kotlin中错误处理生成的方法。如果您愿意,请为项目维护人员提交一份报告

无论如何,为了避免针对这种特殊情况的Jacoco警告,只需查看报告中的代码(第17、18行,…直到
equals
方法的末尾):

  • 将生成的
    equals
    方法的内容临时复制到
    ListNode
    (仅为方便起见)

  • 将代码覆盖率提高到所需的级别

  • 删除
    equals
    方法

  • 代码覆盖率保持在步骤(2)上的状态,因为
    equals
    保持不变(但现在它是隐式创建的)


  • 字节码实际上有两个分支,原因如下

    您正在
    Any?
    上使用扩展名
    hashCode()
    ,因为
    T
    的上限是
    Any?
    ,而不是
    Any
    。此扩展的实现方式如下:

    public.hashCode():Int=this?.hashCode()?:0
    
    这意味着在字节码中,对
    value.hashCode()
    的调用将替换为
    value?.hashCode()?:0

    在您的测试中,您只覆盖
    可能不为空的情况,因此分支
    ?:0
    不包括在内

    在JaCoCo不支持
    inline
    函数之前,这里有两种解决方案:

    • 还包括使用
      null
      T
      测试
      ListNode
      的其他分支
    • 使用
      Any
      作为
      T
      的上限:
    数据类ListNode(变量值:T,变量下一步:ListNode?)
    
    谢谢Giorgio,给了你如此清晰的回答@没问题!
    data class ListNode<T: Any>(var value: T, var next: ListNode<T>?)