JUnit5 Parameterized
@ValueSource — Simple Values
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.*;
// Dependency: junit-jupiter-params
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 5, 8, 13})
void fibonacciNumbers_arePositive(int n) {
assertTrue(n > 0);
}
@ParameterizedTest
@ValueSource(strings = {"alice@example.com", "bob+tag@domain.org", "user@sub.domain.co"})
void validEmails_passValidation(String email) {
assertTrue(EmailValidator.isValid(email));
}
@ParameterizedTest
@ValueSource(longs = {Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE})
void longBoundaries(long value) {
assertNotNull(converter.convert(value));
}
// Supported types: short, byte, int, long, float, double,
// char, boolean, String, Class
@CsvSource & @CsvFileSource
@ParameterizedTest(name = "{0} + {1} = {2}")
@CsvSource({
"1, 1, 2",
"2, 3, 5",
"10, -5, 5",
"'hello world', , 'hello world'", // null second param
})
void add_returnsExpected(int a, int b, int expected) {
assertEquals(expected, calculator.add(a, b));
}
// Empty string vs null
@ParameterizedTest
@CsvSource(value = {
"alice, ACTIVE",
"'', GUEST",
"null, ANONYMOUS",
}, nullValues = "null")
void roleMapping(String name, String role) {
assertEquals(role, resolveRole(name));
}
// From CSV file (resources/test-data/users.csv)
@ParameterizedTest
@CsvFileSource(resources = "/test-data/calc-cases.csv", numLinesToSkip = 1)
void csvFileTest(int input, int expected) {
assertEquals(expected, transform(input));
}
@MethodSource — Complex Objects
import java.util.stream.Stream;
import org.junit.jupiter.params.provider.Arguments;
// Method must return Stream, Iterable, Iterator, or array
static Stream<Arguments> userProvider() {
return Stream.of(
Arguments.of("Alice", 28, true),
Arguments.of("Bob", 17, false), // minor
Arguments.of("Carol", 65, true),
);
}
@ParameterizedTest
@MethodSource("userProvider")
void userEligibility(String name, int age, boolean expectedEligible) {
User user = new User(name, age);
assertEquals(expectedEligible, service.isEligible(user));
}
// External class method
@ParameterizedTest
@MethodSource("com.example.TestData#provideOrders")
void processOrders(Order order, double expectedTotal) {
assertEquals(expectedTotal, processor.calculate(order), 0.01);
}
// No-arg method (single parameter tests)
static Stream<String> validTokens() {
return Stream.of("Bearer abc123", "Bearer xyz789");
}
@ParameterizedTest
@MethodSource("validTokens")
void validToken_passesAuth(String token) {
assertTrue(authService.verify(token));
}
@EnumSource
enum Status { ACTIVE, INACTIVE, SUSPENDED, PENDING }
// All enum constants
@ParameterizedTest
@EnumSource(Status.class)
void statusToString_isNotEmpty(Status status) {
assertFalse(status.toString().isEmpty());
}
// Only specific constants
@ParameterizedTest
@EnumSource(value = Status.class, names = {"ACTIVE", "PENDING"})
void openStatuses_allowLogin(Status status) {
assertTrue(authService.canLogin(status));
}
// Exclude specific constants
@ParameterizedTest
@EnumSource(value = Status.class,
mode = EnumSource.Mode.EXCLUDE,
names = {"SUSPENDED"})
void nonSuspended_canViewContent(Status status) {
assertTrue(contentService.hasAccess(status));
}
// Match by pattern
@ParameterizedTest
@EnumSource(value = Status.class,
mode = EnumSource.Mode.MATCH_ALL,
names = "^(ACTIVE|PENDING)$")
void matchedStatuses(Status status) {
assertNotNull(status);
}
@NullSource, @EmptySource, @NullAndEmptySource
@ParameterizedTest
@NullSource
void nullInput_throwsException(String input) {
assertThrows(NullPointerException.class,
() -> validator.validate(input));
}
@ParameterizedTest
@EmptySource
void emptyInput_returnsEmpty(String input) {
assertEquals("", processor.trim(input));
}
// Combines @NullSource + @EmptySource
@ParameterizedTest
@NullAndEmptySource
@ValueSource(strings = {" ", "\t", "\n"})
void blankInputs_areRejected(String input) {
assertFalse(validator.isValid(input));
}
@ArgumentsSource — Custom Providers
import org.junit.jupiter.params.provider.*;
import java.util.stream.Stream;
// Custom provider class
class UserArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(
ExtensionContext context) {
return Stream.of(
Arguments.of(new User(1L, "Admin"), "admin"),
Arguments.of(new User(2L, "Guest"), "viewer")
);
}
}
@ParameterizedTest
@ArgumentsSource(UserArgumentsProvider.class)
void userRoles(User user, String expectedRole) {
assertEquals(expectedRole, roleService.getRoleFor(user));
}
// Named test display
@ParameterizedTest(name = "[{index}] {0} should be {1}")
@CsvSource({"ACTIVE,true", "BANNED,false"})
void statusActive(String status, boolean expected) {
assertEquals(expected, Status.valueOf(status).isActive());
}