junit5 icon indicating copy to clipboard operation
junit5 copied to clipboard

Add List-based support to Arguments API

Open mariokhoury4 opened this issue 6 months ago • 4 comments

Overview

This PR adds List-based support to the Arguments API for parameterized tests.

New additions:

  • Arguments.of(List<@Nullable Object>)
  • Arguments.arguments(List<@Nullable Object>) (alias)
  • Arguments.argumentSet(String, List<@Nullable Object>)
  • Arguments.toList() — returns a mutable List<@Nullable Object>

These additions make it easier to dynamically build arguments from collections when using @ParameterizedTest.

All additions are tested in ArgumentsTests.java.

Fixes #4535


I hereby agree to the terms of the JUnit Contributor License Agreement.


Definition of Done

mariokhoury4 avatar May 24 '25 22:05 mariokhoury4

One more thing: List<?> is a good enough replacement for List<? extends @Nullable Object>. In this case, the method should probably have a signature like from(Iterable<?>)

vlsi avatar Jun 05 '25 13:06 vlsi

One more thing: List<?> is a good enough replacement for List<? extends @Nullable Object>

I didn't know that but sounds like you're right, according to the spec:

If an unbounded wildcard appears in a null-marked scope, then it has a single upper bound whose base type is Object and whose nullness operator is UNION_NULL.

Therefore, I think using List<?> as method parameter and return type of toList() makes sense.

Just wondering: have you considered Iterable rather than using a plain List?

The use case we're addressing here is constructing new Arguments instances from existing ones so I don't think that flexibility is needed. Moreover, we could introduce it later, if necessary.

marcphilipp avatar Jun 05 '25 15:06 marcphilipp

@marcphilipp , sorry for asking the same thing twice, however, could you please clarify why do you mean Arguments.from(List), Arguments argumentsFrom(List), and ArgumentSet argumentSetFrom(String name, List) relate to "from existing ones"?

To me the second case of #4535 sounds like a natural case for using argumentsFrom(Iterable<?>) rather than a pure List.

  1. An Arguments can only be created from an array, not a collection.

I've no issues if Arguments.toList returns List. However, I believe on the consumption side, Arguments.from should accept Iterable so the users could supply various types of collections they have.

Of course, it would be great if Java had something like IterableWithPredefinedIterationOrder, so users don't accidentally pass HashSet and get their arguments shuffled.


If you mean you force List so the users do not supply collections like Stream...parallel()... and somehow complain "the order of arguments is wrong sometimes"? If that is the case, it is probably worth documenting as "this List<?> could have been Iterable<?>" is a typical code review case.

vlsi avatar Jun 05 '25 15:06 vlsi

sorry for asking the same thing twice, however, could you please clarify why do you mean Arguments.from(List), Arguments argumentsFrom(List), and ArgumentSet argumentSetFrom(String name, List) relate to "from existing ones"?

The use case we're trying to address here is to go from an existing Arguments instance to a new one without re-inventing a new collection API.

I've no issues if Arguments.toList returns List. However, I believe on the consumption side, Arguments.from should accept Iterable so the users could supply various types of collections they have.

We'll discuss that in one of our next team calls.

marcphilipp avatar Jun 06 '25 14:06 marcphilipp