Ответ
JUnit 5 предоставляет несколько механизмов для передачи данных в тесты, в первую очередь через аннотацию @ParameterizedTest.
1. Прямое указание значений (@ValueSource, @EnumSource)
Используется для простых наборов данных.
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
@NullSource
@EmptySource
void testWithSimpleValues(Integer argument) {
assertTrue(argument == null || argument > 0);
}
2. Передача CSV-данных (@CsvSource, @CsvFileSource)
Идеально для пар значений или данных из внешних файлов.
@ParameterizedTest
@CsvSource({
"apple, 1",
"banana, 2",
"'lemon, lime', 3" // Экранирование запятой
})
void testWithCsvSource(String fruit, int rank) {
assertNotNull(fruit);
assertTrue(rank > 0);
}
3. Методы-провайдеры (@MethodSource)
Самый гибкий способ для генерации сложных аргументов.
@ParameterizedTest
@MethodSource("provideUserData")
void testWithComplexObjects(User user, boolean isActive) {
assertEquals(isActive, user.isEnabled());
}
static Stream<Arguments> provideUserData() {
return Stream.of(
Arguments.of(new User("Alice", "admin"), true),
Arguments.of(new User("Bob", "guest"), false)
);
}
4. Кастомные провайдеры через ArgumentsProvider
Для максимального контроля над источником данных (например, из базы данных).
@ParameterizedTest
@ArgumentsSource(MyCustomProvider.class)
void testWithCustomProvider(String data) {
// ...
}
static class MyCustomProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(Arguments.of("data1"), Arguments.of("data2"));
}
}
Ключевой принцип: Источник данных должен возвращать Stream, Iterable, Iterator или массив аргументов, которые будут поочередно переданы в параметризованный тестовый метод.