Custom argument providers let you supply test data in your own way. This helps run the same test with different inputs easily.
0
0
Custom argument providers in JUnit
Introduction
You want to test a method with many different inputs that are not simple lists.
You need to generate test data dynamically, like reading from a file or database.
You want to reuse complex test data setup across multiple tests.
You want to keep your test code clean by separating data generation from test logic.
Syntax
JUnit
public class MyArgumentsProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) { return Stream.of( Arguments.of("input1", 1), Arguments.of("input2", 2) ); } } @ParameterizedTest @ArgumentsSource(MyArgumentsProvider.class) void testWithCustomArguments(String input, int number) { // test code here }
The class must implement ArgumentsProvider interface.
Override provideArguments to return a stream of Arguments.
Examples
This provider returns two sets of arguments: a string and a number.
JUnit
public class SimpleArgumentsProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) { return Stream.of( Arguments.of("apple", 5), Arguments.of("banana", 6) ); } }
This test uses the custom provider to check string lengths.
JUnit
@ParameterizedTest @ArgumentsSource(SimpleArgumentsProvider.class) void testFruitLength(String fruit, int expectedLength) { assertEquals(expectedLength, fruit.length()); }
This provider generates arguments dynamically from a list.
JUnit
public class DynamicArgumentsProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) { List<String> data = List.of("dog", "cat", "bird"); return data.stream().map(s -> Arguments.of(s, s.length())); } }
Sample Program
This test uses a custom argument provider that supplies pairs of words and numbers. The test checks if the word's length matches the number.
JUnit
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; import java.util.stream.Stream; public class CustomArgumentProviderTest { static class NumberWordProvider implements ArgumentsProvider { @Override public Stream<? extends Arguments> provideArguments(ExtensionContext context) { return Stream.of( Arguments.of("one", 3), Arguments.of("two", 3), Arguments.of("three", 5) ); } } @ParameterizedTest @ArgumentsSource(NumberWordProvider.class) void testWordLength(String word, int number) { assertEquals(number, word.length()); } }
OutputSuccess
Important Notes
Custom argument providers help keep tests clean and flexible.
Always return a Stream of Arguments for best compatibility.
Use @ArgumentsSource annotation to link the provider to the test.
Summary
Custom argument providers supply test data in your own way.
Implement ArgumentsProvider and override provideArguments method.
Use @ArgumentsSource to connect the provider to your parameterized test.