What if you could run hundreds of tests with different data by writing just one smart provider?
Why Custom argument providers in JUnit? - Purpose & Use Cases
Imagine you have a test that needs to run many times with different sets of data. You write each test case by hand, copying and changing values over and over.
This feels like filling out a long form again and again without any help.
Manually writing each test case is slow and boring. It's easy to make mistakes like typos or forgetting a case.
When data changes, you must update every test by hand, which wastes time and causes errors.
Custom argument providers let you write one smart piece of code that feeds many test cases automatically.
This means your tests run with all needed data without repeating yourself or risking mistakes.
@Test
void testAdd() {
assertEquals(3, add(1, 2));
assertEquals(5, add(2, 3));
assertEquals(7, add(3, 4));
}@ParameterizedTest
@ArgumentsSource(MyProvider.class)
void testAdd(int a, int b, int expected) {
assertEquals(expected, add(a, b));
}You can easily run many test cases with complex or changing data, all managed in one place.
Testing a calculator app with many input combinations, like positive, negative, zero, and large numbers, without writing separate tests for each.
Manual test data writing is slow and error-prone.
Custom argument providers automate feeding data to tests.
This saves time and reduces mistakes in testing.
Practice
Solution
Step 1: Understand the role of argument providers
Argument providers supply data to parameterized tests, allowing tests to run multiple times with different inputs.Step 2: Identify the purpose of custom argument providers
Custom argument providers let you define your own way to supply test data beyond built-in sources.Final Answer:
To supply test data to parameterized tests in a custom way -> Option CQuick Check:
Custom argument providers = supply test data [OK]
- Confusing argument providers with test method creators
- Thinking they replace @Test annotation
- Assuming they generate reports
Solution
Step 1: Recall JUnit interfaces for argument providers
The interface to implement for custom argument providers is ArgumentsProvider.Step 2: Differentiate from other interfaces
ArgumentsSource is an annotation, not an interface. The others serve different purposes.Final Answer:
ArgumentsProvider -> Option BQuick Check:
Implement ArgumentsProvider for custom data [OK]
- Confusing ArgumentsSource annotation with interface
- Choosing unrelated interfaces
- Not overriding provideArguments method
public class MyProvider implements ArgumentsProvider {
@Override
public Stream<Arguments> provideArguments(ExtensionContext context) {
return Stream.of(Arguments.of("apple"), Arguments.of("banana"));
}
}
@ParameterizedTest
@ArgumentsSource(MyProvider.class)
void testFruits(String fruit) {
System.out.println(fruit);
}Solution
Step 1: Analyze the provideArguments method
The method returns a stream with two Arguments: "apple" and "banana".Step 2: Understand parameterized test execution
The test runs twice, once with "apple" and once with "banana", printing each on its own line.Final Answer:
apple\nbanana (each on separate lines) -> Option AQuick Check:
Stream of Arguments runs test twice [OK]
- Assuming output is on one line
- Thinking code has syntax errors without imports
- Confusing method signature correctness
public class BadProvider implements ArgumentsProvider {
public Stream<Arguments> provideArguments() {
return Stream.of(Arguments.of(1), Arguments.of(2));
}
}Solution
Step 1: Check method signature requirements
The provideArguments method must override the interface method and accept ExtensionContext as a parameter.Step 2: Identify the missing parameter
The code's provideArguments method lacks the ExtensionContext parameter, causing a signature mismatch.Final Answer:
Method provideArguments must have ExtensionContext parameter -> Option AQuick Check:
Correct method signature requires ExtensionContext [OK]
- Ignoring method signature parameters
- Thinking @Override is mandatory but not fixing signature
- Confusing Arguments.of() usage
public class DoubleProvider implements ArgumentsProvider {
@Override
public Stream<Arguments> provideArguments(ExtensionContext context) {
// Fill in the blank
}
}Solution
Step 1: Understand the requirement
Each pair must have the second integer double the first.Step 2: Evaluate each option
return Stream.of(Arguments.of(1, 2), Arguments.of(2, 4), Arguments.of(3, 6)); correctly pairs (1,2), (2,4), (3,6). Other options provide pairs like (1,3),(2,5),(3,7) or equal numbers (1,1),(2,2),(3,3), or an empty stream.Final Answer:
return Stream.of(Arguments.of(1, 2), Arguments.of(2, 4), Arguments.of(3, 6)); -> Option DQuick Check:
Second integer = 2 * first integer [OK]
- Providing pairs where second is not double
- Returning empty stream by mistake
- Confusing argument order
Ready to prove it?
Pass the test and this pattern moves unknown
