In JUnit 5, @ValueSource is used with @ParameterizedTest to run the same test multiple times with different simple literal values.
Basic example
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
class StringTest {
@ParameterizedTest
@ValueSource(strings = {"racecar", "radar", "level"})
void palindromeWordsHaveLengthGreaterThanZero(String word) {
assertTrue(word.length() > 0);
}
}
This test runs 3 times, once for each value:
racecar
radar
level
Supported @ValueSource types
@ValueSource supports arrays of simple values such as:
@ValueSource(strings = {"apple", "banana"})
@ValueSource(ints = {1, 2, 3})
@ValueSource(longs = {10L, 20L})
@ValueSource(doubles = {1.5, 2.5})
@ValueSource(booleans = {true, false})
@ValueSource(chars = {'a', 'b'})
@ValueSource(classes = {String.class, Integer.class})
Example with integers:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
class NumberTest {
@ParameterizedTest
@ValueSource(ints = {2, 4, 6, 8})
void numbersAreEven(int number) {
assertTrue(number % 2 == 0);
}
}
Important limitation
@ValueSource can provide only one argument per test invocation.
So this works:
@ParameterizedTest
@ValueSource(strings = {"hello", "world"})
void testSingleArgument(String value) {
// test logic
}
But this does not work with @ValueSource:
@ParameterizedTest
@ValueSource(strings = {"hello", "world"})
void testMultipleArguments(String input, int expectedLength) {
// invalid for @ValueSource
}
For multiple arguments, use @CsvSource, @MethodSource, or @ArgumentsSource.
Example with empty and blank strings
@ValueSource can be combined with other parameter sources:
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EmptySource;
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.assertTrue;
class BlankStringTest {
@ParameterizedTest
@NullSource
@EmptySource
@ValueSource(strings = {" ", " ", "\t", "\n"})
void stringIsBlank(String value) {
assertTrue(value == null || value.isBlank());
}
}
This runs with:
null
""
" "
" "
"\t"
"\n"
Maven dependency
Make sure you have JUnit Jupiter Params on the test classpath:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
If you use Spring Boot, this is usually included through:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Summary
Use @ValueSource when your parameterized test needs one simple value per run:
@ParameterizedTest
@ValueSource(strings = {"a", "b", "c"})
void test(String value) {
// runs once for each value
}
