How do I use @EnumSource to test enum values?

@EnumSource is a JUnit 5 parameterized-test source that runs the same test once for each selected enum constant.

Basic usage

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertNotNull;

class DirectionTest {

    enum Direction {
        NORTH, SOUTH, EAST, WEST
    }

    @ParameterizedTest
    @EnumSource(Direction.class)
    void shouldTestAllDirections(Direction direction) {
        assertNotNull(direction);
    }
}

This runs the test 4 times: once with NORTH, SOUTH, EAST, and WEST.

Test only specific enum values

Use names to include selected constants:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertTrue;

class DirectionTest {

    enum Direction {
        NORTH, SOUTH, EAST, WEST
    }

    @ParameterizedTest
    @EnumSource(value = Direction.class, names = {"NORTH", "EAST"})
    void shouldTestOnlyNorthAndEast(Direction direction) {
        assertTrue(direction == Direction.NORTH || direction == Direction.EAST);
    }
}

Exclude specific enum values

Use mode = EnumSource.Mode.EXCLUDE:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertNotEquals;

class DirectionTest {

    enum Direction {
        NORTH, SOUTH, EAST, WEST
    }

    @ParameterizedTest
    @EnumSource(
        value = Direction.class,
        names = {"WEST"},
        mode = EnumSource.Mode.EXCLUDE
    )
    void shouldTestAllExceptWest(Direction direction) {
        assertNotEquals(Direction.WEST, direction);
    }
}

This runs for NORTH, SOUTH, and EAST.

Match enum names with a regex

Use mode = EnumSource.Mode.MATCH_ANY:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertTrue;

class DirectionTest {

    enum Direction {
        NORTH, SOUTH, EAST, WEST
    }

    @ParameterizedTest
    @EnumSource(
        value = Direction.class,
        names = {"N.*", "E.*"},
        mode = EnumSource.Mode.MATCH_ANY
    )
    void shouldTestNamesStartingWithNOrE(Direction direction) {
        assertTrue(direction.name().startsWith("N") || direction.name().startsWith("E"));
    }
}

This runs for NORTH and EAST.

Common modes

EnumSource.Mode.INCLUDE     // default; include listed names
EnumSource.Mode.EXCLUDE     // exclude listed names
EnumSource.Mode.MATCH_ANY   // include names matching any regex
EnumSource.Mode.MATCH_ALL   // include names matching all regexes

Typical real-world example

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;

import static org.junit.jupiter.api.Assertions.assertTrue;

class OrderStatusTest {

    enum OrderStatus {
        NEW, PAID, SHIPPED, CANCELLED
    }

    @ParameterizedTest
    @EnumSource(value = OrderStatus.class, names = {"PAID", "SHIPPED"})
    void completedStatusesShouldBeProcessed(OrderStatus status) {
        assertTrue(status == OrderStatus.PAID || status == OrderStatus.SHIPPED);
    }
}

In short:

@ParameterizedTest
@EnumSource(MyEnum.class)
void test(MyEnum value) {
    // test each enum value
}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.