简体   繁体   中英

Jacoco complains about unlikely missing branch coverage

I'm using Gradle 6.3 and Jacoco to compile, test and show coverage report. But I fail to understand why it complains there is "1 of 2 branches missed", there is no branch at all:

错过了 2 个分支中的 1 个

Here is the complete Kotlin data class:

data class ListNode<T>(var value: T, var next: ListNode<T>?) {

    override fun hashCode(): Int = value.hashCode()

}

If somehow there are branches behind the scene, what are they and how do I cover them?

There are actually two branches in the bytecode and here is why.

You are using the extension hashCode() on Any? since the T 's upper bound is Any? , not Any . This extension is implemented like so:

public inline fun Any?.hashCode(): Int = this?.hashCode() ?: 0

This means that in the bytecode, your call to value.hashCode() is replaced with value?.hashCode()?: 0 .

In your test you are covering only the case in which value is not null probably, so the branch ?: 0 isn't covered.

You have two solutions here until JaCoCo won't support inline functions:

  • cover also the other branch testing a ListNode using a null T .
  • use Any as the T 's upper bound:
data class ListNode<T: Any>(var value: T, var next: ListNode<T>?)

A data class in Kotlin has default auto-generated methods ( equals , toString , hashCode , getters, setters). In this case we're talking about equals . It is not visible in the code of class ListNode , but its JVM bytecode definitely contains equals , toString , etc.

Jacoco is mostly targeted for Java Co de Co verage, so this situation, probably, may be treated as a Jacoco's incorrect handling of generated methods in Kotlin. If you wish - commit an issue for the project maintainers.

Anyways, to avoid Jacoco warnings for this particular case, just look at the code in the report (lines 17,18,.. up to the end of the equals method):

  1. temporarily copy contents of generated equals method to the ListNode (just for own convenience)

  2. increase the code coverage to the needed level

  3. erase the equals method

  4. code coverage remain as it was on step (2), because equals remains the same (but now it is created implicitly)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM