Search code examples
junitenumskotlinkotlintest

Test all enums implementing the marker interface


I have the empty interface interface HavingUniqueValues(val v: Int) {} and some enums like enum class EnumName(override val v: Int) : HavingUniqueValues.

I want the elements in each enum have unique v-values but I can mistype the values. So I need a test.

  1. Is it possible to create a test where the interface implementations are saved as a List manually and the test checks if all the implementations in the List meet the requirement?
  2. If yes: is it possible to create a function that returns the List of all implementations in the specified package to use it in the test?

Solution

  • Take a look at the Reflections library which might aid you with this.

    You should be able to get all subtypes of HavingUniqueValues:

    val subjects: Set<Class<out HavingUniqueValues>> =
            Reflections("your.package").getSubTypesOf(HavingUniqueValues::class.java)
    

    Now, this will result in a Set of all enum classes that implement HavingUniqueValues. You can iterate all of their values to know if they are unique or not:

    subjects.forEach { enumClass ->
        assertEquals(
                enumClass.enumConstants.size,
                enumClass.enumConstants.map(HavingUniqueValues::v).toSet().size
        )
    }
    

    I used toSet() here to drop all non-inuque values.

    This will pass the test:

    enum class EnumName(override val v: Int) : HavingUniqueValues { ONE(1), TWO(2), THREE(3) }
    

    This will not pass the test:

    enum class EnumName(override val v: Int) : HavingUniqueValues { ONE(1), TWO(2), THREE(2) }