【问题标题】:Jacoco coverage and Kotlin default parametersJacoco 覆盖率和 Kotlin 默认参数
【发布时间】:2016-06-11 12:54:34
【问题描述】:

我有以下构造函数:

open class IPFS @JvmOverloads constructor(protected val base_url: String = "http://127.0.0.1:5001/api/v0/",
                                          protected val okHttpClient: OkHttpClient = OkHttpClient.Builder().build(),
                                          protected val moshi: Moshi = Moshi.Builder().build()) {

现在,在测量覆盖率时,使用默认值时我总是会错过。我能想象的唯一出路是在 java 中编写一些使用其他构造函数的测试——但我想留在纯 kotlin 中——有没有办法做到这一点?

更新:我在测试中使用了像 IPFS() 这样的构造函数——但我认为在生成的 java 字节码上,它被转换为带有所有 3 个参数的构造函数——这是 jacoco 看到的唯一东西

【问题讨论】:

  • 从技术上讲,您在字节码中有四个构造函数,并且您只调用其中一个。这与 Java 中的相同。
  • 我正在调用不同的构造函数 - 但 jacoco 只看到一个构造函数
  • 啊,正好相反。有道理。
  • 你怎么知道你调用了不同的构造函数?在 kotlin 中,只有一个应该是可见的(带有矩阵的那个)

标签: java code-coverage kotlin jacoco


【解决方案1】:

由于您使用 @JvmOverloads 注释,编译器将生成 3 个重载的构造函数。该注解主要用于在纯Java中可以省略参数。

@Target([AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR])
annotation class JvmOverloads

指示 Kotlin 编译器 为这个函数生成替代默认值的重载 参数值。

如果一个方法有N个参数,其中M个有默认值,M个 产生重载:第一个采用 N-1 个参数(除了 最后一个取默认值),第二个取 N-2 参数等等。

在 Kotlin 中使用任意数量的参数调用构造函数时,将调用默认的 3 参数构造函数 - 其中 default values 用于省略的参数。
因此,Jacoco 没有将重载标记为已覆盖是有道理的:它们不是。

就像@voddan 所说,这些重载是生成的,并保证正确。单独测试这些没有多大意义。

但是,如果您确实想要完全覆盖,请删除 @JvmOverloads 注释。这应该可以防止产生额外的重载。

如果您因为将从 Java 调用重载的构造函数而无法删除注释,那么拥有涵盖这些内容的 Java 测试套件毕竟是有意义的:这是您想要涵盖的真实世界场景。

【讨论】:

  • 技术上“默认的三参数构造函数”有4个参数(最后一个是掩码)
【解决方案2】:

您确定需要 100% 覆盖这些构造函数吗?这些构造函数由编译器自动生成,从而保证了它们的正确性(比代码覆盖范围更大)。

IMO 使用所有自定义参数测试构造函数就足够了。对所有默认参数的附加测试可能涵盖默认值的计算。

总的来说,测试自动生成的代码可能不是最好的主意。

【讨论】:

  • 我希望整体覆盖率高
  • @ligi 在您的代码中添加不必要的魔法只是为了在报告中获得更好的数字是不好的做法,您应该避免它。只需确保涵盖了您最重要的方法即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 2013-02-07
相关资源
最近更新 更多