Jacoco 覆盖率和 Kotlin 默认参数

Jacoco coverage and Kotlin default parameters

我有以下构造函数:

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 唯一看到的

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

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

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

由于您使用的是 @JvmOverloads 注释,编译器将生成 3 个重载的构造函数。这个注解主要是为了能够在plain中省略参数Java.

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

Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.

If a method has N parameters and M of which have default values, M overloads are generated: the first one takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.

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

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

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

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