11

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

我知道在 Kotlin 中使用 @MethodSource 的两种方法 - 伴生对象和 @TestInstance(TestInstance.Lifecycle.PER_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$4(MethodArgumentsProvider.java:83)
4

2 回答 2

23

最好的解决方案是向@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)
            )
        }
    }
}
于 2020-09-14T14:12:58.707 回答
13

JUnit 文档

可以通过提供其完全限定的方法名称来引用外部静态工厂方法,如下例所示。

Kotlin文档说

在包 org.example 内的文件 app.kt 中声明的所有函数和属性,包括扩展函数,都被编译为名为 org.example.AppKt 的 Java 类的静态方法。

因此,如果包名是com.test.enums(来自错误消息),并且您的文件名是GenerationStatusTest.kt,那么生成的类包含provideStatusesToTestis com.test.GenerationStatusTestKt,所以您需要的注释是

@MethodSource("com.test.enums.GenerationStatusTestKt#provideStatusesToTest")
于 2019-07-16T10:14:41.740 回答