Published on

Using JUnit 5's @EnumSource to Test Code That Uses Enums as Input

Authors

Today I needed to test a method in my code that took an enum as input. This method had an if statement that did something for one enum and the else did something else for the rest of the enum values. Using JUnit 5's @ParameterizedTest with @EnumSource this is significantly easier to test succinctly.

I have an enum say of compass points:

enum class CompassPoint {
    NORTH, SOUTH, EAST, WEST
}

And I have code that does one thing if it is CompassPoint.NORTH but something else if it is any of the others:

object NavigationUtil {

 fun navigate(point: CompassPoint): String{
      if(point == CompassPoint.NORTH){
         return "do something"
      }
      else{
        return "do something else"
      }
 }

}

I can easily write tests for SOUTH, EAST and WEST as follows:

@ParameterizedTest
@EnumSource(
   value = CompassPoint::class,
   names = arrayOf("SOUTH", "EAST", "WEST")
)
fun `navigating SOUTH EAST or WEST does something else`(point: CompassPoint){
    assertEquals("do something else", NavigationUtil.navigate(point))
}

This will execute the test 3 times. For each execution this:

  • takes a string element from the names array (i.e. arrayOf("SOUTH", "EAST", "WEST"))
  • coverts that to an enum
  • passes the enum as the method parameter point
  • runs the code in your test using this method parameter

It runs all of these and if one fails shows which one failed.

One thing that tripped me up at first is that if you annotate this as @Test and a @ParameterizedTest as below:

@ParameterizedTest
@Test
@EnumSource(
   value = CompassPoint::class,
   names = arrayOf("SOUTH", "EAST", "WEST")
)
fun `navigating SOUTH EAST or WEST does something else`(point: CompassPoint){
...

You will then get an error similar to:

org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [my.company.enumeration.CompassPoint arg0] in executable [public final void my.company.enumeration.NavigationUtilTest.calculateOrdinal None NORTHs uses the correct formula(my.company.enumeration.Ordinals)].

If you simply delete the @Test annotation your test will run fine.