- Published on
Using JUnit 5's @EnumSource to Test Code That Uses Enums as Input
- Authors
- Name
- Yair Mark
- @yairmark
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.