Labs ICT
โญ Pro Login

ValueSource, CsvSource, MethodSource

Let us take a deeper look at the different argument sources available for parameterized tests. Each source is designed for a specific use case, and knowing when to use each one will make your tests more readable and maintainable.

@ValueSource

The simplest source. Provides single values of the same type:


@ParameterizedTest
@ValueSource(strings = {"a", "ab", "abc", "abcd"})
void stringsOfIncreasingLength(String s) {
    assertTrue(s.length() > 0);
}

@ParameterizedTest
@ValueSource(ints = {1, 3, 5, 7, 9})
void oddNumbers(int n) {
    assertEquals(1, n % 2);
}

@ParameterizedTest
@ValueSource(doubles = {1.0, 2.5, 3.14})
void positiveDoubles(double d) {
    assertTrue(d > 0);
}

@ParameterizedTest
@ValueSource(booleans = {true, false})
void allBooleans(boolean b) {
    assertNotNull(Boolean.valueOf(b));
}
    

Supported types: String, int, long, double, float, short, byte, char, boolean.

@CsvSource

Provides multiple arguments per invocation using comma-separated values:


@ParameterizedTest
@CsvSource({
    "apple, 5",
    "banana, 6",
    "'hello world', 11",
    "a, 1"
})
void stringLength(String word, int expectedLength) {
    assertEquals(expectedLength, word.length());
}

// With explicit delimiters
@ParameterizedTest
@CsvSource(delimiter = '|', useHeadersInDisplayName = true, textBlock = """
    INPUT    | EXPECTED
    hello    | 5
    world    | 5
    junit    | 5
    """)
void length(String input, int expected) {
    assertEquals(expected, input.length());
}
    

@CsvFileSource

When you have lots of test data, put it in a CSV file:


// src/test/resources/test-data.csv
// input,expected
// hello,5
// world,5
// junit,5
// "",0
// "a",1

@ParameterizedTest
@CsvFileSource(
    resources = "/test-data.csv",
    numLinesToSkip = 1
)
void stringLength(String input, int expected) {
    assertEquals(expected, input.length());
}
    

@MethodSource

The most flexible source. Provide arguments from a static method:


// Simple stream of values
@ParameterizedTest
@MethodSource("singleValues")
void testSingle(String value) {
    assertNotNull(value);
}

static Stream<String> singleValues() {
    return Stream.of("alpha", "beta", "gamma");
}

// Stream of Arguments for multiple params
@ParameterizedTest
@MethodSource("calculationData")
void testCalculation(int a, int b, int expected) {
    assertEquals(expected, calc.add(a, b));
}

static Stream<Arguments> calculationData() {
    return Stream.of(
        Arguments.of(1, 1, 2),
        Arguments.of(0, 0, 0),
        Arguments.of(-1, 1, 0),
        Arguments.of(Integer.MAX_VALUE, 0, Integer.MAX_VALUE)
    );
}

// Factory method pattern
@ParameterizedTest
@MethodSource("com.example.TestDataFactory#userScenarios")
void testUserScenarios(User user, boolean expected) {
    assertEquals(expected, service.isValid(user));
}
    

@EnumSource


// Test all enum values
@ParameterizedTest
@EnumSource(TimeUnit.class)
void allTimeUnits(TimeUnit unit) {
    assertNotNull(unit);
    assertTrue(unit.toMillis(1) > 0);
}

// Select specific values
@ParameterizedTest
@EnumSource(value = TimeUnit.class,
            names = {"SECONDS", "MINUTES", "HOURS"})
void selectedTimeUnits(TimeUnit unit) {
    assertTrue(unit.toMillis(1) > 0);
}

// Exclude specific values
@ParameterizedTest
@EnumSource(value = TimeUnit.class,
            mode = EnumSource.Mode.EXCLUDE,
            names = {"NANOSECONDS", "MICROSECONDS"})
void nonMicroUnits(TimeUnit unit) {
    assertTrue(unit.toMillis(1) >= 1);
}
    

@ArgumentsSource - Custom Provider


class CustomArgumentsProvider implements ArgumentsProvider {

    @Override
    public Stream<? extends Arguments> provideArguments(
            ExtensionContext context) {
        return Stream.of(
            Arguments.of("input1", "expected1"),
            Arguments.of("input2", "expected2"),
            Arguments.of("input3", "expected3")
        );
    }
}

@ParameterizedTest
@ArgumentsSource(CustomArgumentsProvider.class)
void customSource(String input, String expected) {
    assertEquals(expected, transform(input));
}
    

Decision Guide


Need single values?              โ†’ @ValueSource
Multiple values, same line?      โ†’ @CsvSource
Lots of data?                    โ†’ @CsvFileSource
Complex objects?                 โ†’ @MethodSource
Enum values?                     โ†’ @EnumSource
Full control?                    โ†’ @ArgumentsSource
    

๐Ÿงช Quick Quiz

What does @CsvSource provide to a parameterized test?