Test Overview
This test demonstrates how to use argument aggregation in JUnit 5 to combine multiple arguments into a single object for parameterized tests. It verifies that the aggregated object correctly holds the combined values.
This test demonstrates how to use argument aggregation in JUnit 5 to combine multiple arguments into a single object for parameterized tests. It verifies that the aggregated object correctly holds the combined values.
import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.aggregator.AggregateWith; import org.junit.jupiter.params.aggregator.ArgumentsAccessor; import org.junit.jupiter.params.provider.CsvSource; class User { String name; int age; User(String name, int age) { this.name = name; this.age = age; } } class UserAggregator implements org.junit.jupiter.params.aggregator.ArgumentsAggregator { @Override public User aggregateArguments(ArgumentsAccessor accessor, java.lang.reflect.Parameter parameter) { return new User(accessor.getString(0), accessor.getInteger(1)); } } public class ArgumentAggregationTest { @ParameterizedTest @CsvSource({"Alice,30", "Bob,25"}) void testUserAggregation(@AggregateWith(UserAggregator.class) User user) { assertEquals("Alice", user.name, "First user's name should be Alice"); assertEquals(30, user.age, "First user's age should be 30"); } @ParameterizedTest @CsvSource({"Alice,30", "Bob,25"}) void testUserAggregationDynamic(@AggregateWith(UserAggregator.class) User user) { if (user.name.equals("Alice")) { assertEquals(30, user.age); } else if (user.name.equals("Bob")) { assertEquals(25, user.age); } else { throw new AssertionError("Unexpected user name: " + user.name); } } }
| Step | Action | System State | Assertion | Result |
|---|---|---|---|---|
| 1 | Test runner starts and loads ArgumentAggregationTest class | JUnit test environment initialized | — | PASS |
| 2 | JUnit invokes testUserAggregation with first CSV input: "Alice,30" | Test method called with aggregated User object (name=Alice, age=30) | assertEquals("Alice", user.name) and assertEquals(30, user.age) | PASS |
| 3 | JUnit invokes testUserAggregation with second CSV input: "Bob,25" | Test method called with aggregated User object (name=Bob, age=25) | assertEquals("Alice", user.name) fails because user.name is "Bob" | FAIL |
| 4 | JUnit invokes testUserAggregationDynamic with first CSV input: "Alice,30" | Test method called with aggregated User object (name=Alice, age=30) | assertEquals(30, user.age) for user.name == "Alice" | PASS |
| 5 | JUnit invokes testUserAggregationDynamic with second CSV input: "Bob,25" | Test method called with aggregated User object (name=Bob, age=25) | assertEquals(25, user.age) for user.name == "Bob" | PASS |
@ArgumentsAggregator in JUnit parameterized tests?public class PersonAggregator implements ArgumentsAggregator {
@Override
public Person aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) {
return new Person(accessor.getString(0), accessor.getInteger(1));
}
}
@ParameterizedTest
@CsvSource({"Alice,30", "Bob,25"})
void testPerson(@AggregateWith(PersonAggregator.class) Person person) {
assertTrue(person.getAge() > 20);
}public class ProductAggregator implements ArgumentsAggregator {
@Override
public Product aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) {
String name = accessor.getString(0);
int price = accessor.getInteger(1);
return new Product(name, price);
}
}
@ParameterizedTest
@CsvSource({"Laptop,1000", "Phone,abc"})
void testProduct(@AggregateWith(ProductAggregator.class) Product product) {
assertNotNull(product);
}Person object with fields name and age. You have CSV data with columns name, age, and city. How can you write a custom aggregator to ignore the city column and only aggregate name and age into Person?Pass the test and this pattern moves unknown