Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use pure Kotlin function as Junit5 methodsource

I am curious if in the Kotlin, in the parameterized tests in Junit5, i can use the method outside the class as the @MethodSource.

I know about 2 ways to use @MethodSource in Kotlin - companion object and @TestInstance(TestInstance.Lifecycle.PER_CLASS). I wonder if it can be done in a different way, for example by declaring a method outside the class and using some annotation? I tried to do it this way, but it does not work, I wonder if something similar can be done.

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)
like image 838
Failed Avatar asked Jul 16 '19 09:07

Failed


2 Answers

The best solution is adding @JvmStatic annotation to your provider function.

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)
            )
        }
    }
}
like image 84
Cafer Mert Ceyhan Avatar answered Oct 21 '22 05:10

Cafer Mert Ceyhan


JUnit documentation says

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

And Kotlin documentation says

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.

So if the package name is com.test.enums (from the error message), and your file name is GenerationStatusTest.kt, then the generated class containing provideStatusesToTest is com.test.GenerationStatusTestKt, so the annotation you need is

@MethodSource("com.test.enums.GenerationStatusTestKt#provideStatusesToTest")
like image 43
Alexey Romanov Avatar answered Oct 21 '22 07:10

Alexey Romanov