Replies: 4 comments
-
Hi Alex, every aggregator sees the entire list of arguments, in other words arguments are not consumed by previous aggregators. The index of the declared parameter within the method does not contain enough information how many arguments are already consumed. One solution is to provided additional information to the aggregators, at which index they should start to aggregate. For example, with proper error/range checks not implemented, like this: import static org.junit.jupiter.api.Assertions.*;
import java.lang.annotation.*;
import org.junit.jupiter.api.extension.*;
import org.junit.jupiter.params.*;
import org.junit.jupiter.params.aggregator.*;
import org.junit.jupiter.params.provider.*;
class ExampleTest {
record X(int a, int b) {}
record Y(int a, int b, int c) {}
@ParameterizedTest
@CsvSource(
value = {
"1, 2, 3, 4, 5",
})
void test1(@AggregateWith(AsX.class) X x, @AggregateWith(AsY.class) @StartIndex(2) Y y) {
assertEquals(new X(1, 2), x);
assertEquals(new Y(3, 4, 5), y);
}
@ParameterizedTest
@CsvSource(
value = {
"1, 2, 3, 4, 5",
})
void test2(@AggregateWith(AsY.class) Y y, @AggregateWith(AsX.class) @StartIndex(3) X x) {
assertEquals(new X(4, 5), x);
assertEquals(new Y(1, 2, 3), y);
}
static class AsX implements ArgumentsAggregator {
@Override
public X aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) {
int start = getStartIndex(context);
return new X(accessor.getInteger(start), accessor.getInteger(start + 1));
}
}
static class AsY implements ArgumentsAggregator {
@Override
public Y aggregateArguments(ArgumentsAccessor accessor, ParameterContext context) {
int start = getStartIndex(context);
return new Y(
accessor.getInteger(start),
accessor.getInteger(start + 1),
accessor.getInteger(start + 2));
}
}
static int getStartIndex(ParameterContext context) {
StartIndex annotation = context.getParameter().getAnnotation(StartIndex.class);
return annotation == null ? 0 : annotation.value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@interface StartIndex {
int value();
}
} |
Beta Was this translation helpful? Give feedback.
-
Hi Christian, That is certainly a possibility, but it involves hardcoding the data. It would be nice if Junit would provide a method for this. The aggregators are called in order. Perhaps context could show the mapping between the parameters and the arguments, or perhaps the accessor could show the arguments that are (un)access or simply the highest, or something like that. |
Beta Was this translation helpful? Give feedback.
-
Another option would be to use the @beforeeach method in combination with a static method and variable. This requires that each parameter is created using an own aggregator. Also not ideal. |
Beta Was this translation helpful? Give feedback.
-
I made a request for a new feature here: #2778 |
Beta Was this translation helpful? Give feedback.
-
I am having trouble with using multiple aggregators. I can get the index of the parameter, but I want the index of the CSV argument. Any ideas? I have included some sample code below.
Beta Was this translation helpful? Give feedback.
All reactions