使用纯 Kotlin 函数作为 Junit5 方法源

Use pure Kotlin function as Junit5 methodsource

我很好奇在 Kotlin 中,在 Junit5 的参数化测试中,我是否可以使用 class 之外的方法作为 @MethodSource。

我知道在 Kotlin 中使用 @MethodSource 的 2 种方法 - 伴随对象和 @TestInstance(TestInstance.Lifecycle.PER_CLASS)。我想知道它是否可以用不同的方式完成,例如通过在 class 之外声明一个方法并使用一些注释?我试过这样做,但是不行,我想知道是否可以做类似的事情。

class GenerationStatusTest {

    @ParameterizedTest
    @MethodSource("provideStatusesToTest")
    internal fun shouldStatusesHaveExpectedAbilities(generationStatus: GenerationStatus, assertions:(GenerationStatus)->Unit) {
        assertions(generationStatus)
    }
}

fun provideStatusesToTest(): Stream<Arguments> {
    return Stream.of(
            Arguments.of(WAITING, canDoNothing),
            Arguments.of(PROCESSING, canDoNothing)
    )
}
org.junit.platform.commons.JUnitException: Could not find factory method [provideStatusesToTest] in class [com.test.enums.GenerationStatusTest]
    at org.junit.jupiter.params.provider.MethodArgumentsProvider.lambda$getMethod(MethodArgumentsProvider.java:83)

JUnit documentation

An external, static factory method can be referenced by providing its fully qualified method name as demonstrated in the following example.

并且Kotlin documentation

All the functions and properties declared in a file app.kt inside a package org.example, including extension functions, are compiled into static methods of a Java class named org.example.AppKt.

所以如果包名是com.test.enums(来自错误信息),而你的文件名是GenerationStatusTest.kt,那么生成的class包含provideStatusesToTestcom.test.GenerationStatusTestKt,所以你需要的注解是

@MethodSource("com.test.enums.GenerationStatusTestKt#provideStatusesToTest")

最好的解决方案是向您的提供程序函数添加 @JvmStatic 注释。

class SumTest {

    @ParameterizedTest(name = "{0} + {1} = {2}")
    @MethodSource("sumProvider")
    fun sum(a: Int, b: Int, expected: Int) {
        Truth.assertThat((a + b)).isEqualTo(expected)
    }

    companion object {
        @JvmStatic
        fun sumProvider(): Stream<Arguments> {
            return Stream.of(
                    Arguments.of(1, 2, 3),
                    Arguments.of(5, 10, 15)
            )
        }
    }
}