我很好奇在 Kotlin 中,在 Junit5 的参数化测试中,我是否可以使用类外的方法作为@MethodSource。
我知道在 Kotlin 中使用 @MethodSource 的 2 种方法 - 伴侣对象和 @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)
最好的解决方案是将@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)
)
}
}
}
JUnit 文档说
可以通过提供外部静态工厂方法名称来引用其完全限定的方法名称,如以下示例所示。
Kotlin 文档说
在包 org.example 内的文件 app.kt 中声明的所有函数和属性(包括扩展函数(都编译为名为 org.example.AppKt 的 Java 类的静态方法。
因此,如果包名是com.test.enums
(来自错误消息(,并且您的文件名是GenerationStatusTest.kt
,则生成的包含provideStatusesToTest
的类是com.test.GenerationStatusTestKt
,因此您需要的注释是
@MethodSource("com.test.enums.GenerationStatusTestKt#provideStatusesToTest")
我按照这里的答案调整了 Kotlin 中的测试,这就是它的工作原理:
import org.junit.Assert.assertNotNull
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
class ParametrizedTestTest {
companion object {
@JvmStatic fun hashMapProvider() = mapOf(
"1" to "Obj1",
"2" to "Obj2"
).entries
}
@ParameterizedTest
@MethodSource("hashMapProvider")
fun testMyMapObj(argument: Map.Entry<String, Any>) {
assertNotNull(argument)
}
}