Search code examples
kotlinjunitparameterized-unit-test

Kotlin Junit5 ValueSource as an array variable


I have a map of key and values and I want to add the keys as array to ValueSource but I've got error.Where am I wrong?

Here's my code

   private val id = mapOf("abc" to 10001,"def" to 955,"ghi" to 804,"jkl" to 805)
    private val ids:Array<String> = id.keys.toTypedArray()
    
    @ParameterizedTest
    @ValueSource(strings = ids)
    fun idConverterImpl(memberId: String) {
}

Solution

  • The arguments to annotations must be compile time constants. ids is not a compile time constant. It is the value of id.keys.toTypedArray(), which must be computed at runtime.

    You can instead write it inline like this:

    @ParameterizedTest
    @ValueSource(strings = ["abc", "def", "ghi", "jkl"])
    fun idConverterImpl(memberId: String) { ... }
    

    If you don't want to duplicate the keys of your map in multiple places, you can instead use a MethodSource. This allows you to non compile-time constants as the parameters of your test, by providing a method that will generate the parameters.

    You will need to make your map and values static:

    companion object {
        @JvmStatic
        private val id = mapOf("abc" to 100016040, "def" to 955803, "ghi" to 955804, "jkl" to 955805)
    
        @JvmStatic
        private val ids by lazy { id.keys }
    }
    

    By using a property delegate on ids, I made Kotlin generate a getIds method, that I can then refer to using MethodSource:

    @ParameterizedTest
    @MethodSource("getIds")
    fun idConverterImpl(memberId: String) { ... }