Skip to content

Parameterized tests using annotations as the argument source and a deprecated provideArguments method fail to execute in 5.13.0 #4610

Closed
@salockhart

Description

@salockhart

Steps to reproduce

  1. Create a subclass of AnnotationBasedArgumentsProvider that implements provideArguments(ExtensionContext context, CsvSource annotation)
  2. Use that provider as an argument to @ArgumentsSource on a @ParameterizedTest method.

An example follows:

@Retention(RetentionPolicy.RUNTIME)
@Repeatable(TestDefinition.List.class)
public @interface TestDefinition {
    String foo() default "";
    String bar() default "";

    @Retention(RetentionPolicy.RUNTIME)
    @interface List { TestDefinition[] value() default {}; }

    class Provider extends AnnotationBasedArgumentsProvider<TestDefinition.List> {
        @Override
        protected Stream<? extends Arguments> provideArguments(ExtensionContext ctx, TestDefinition.List ann) {
            return Arrays.stream(ann.value()).map(Arguments::arguments);
        }
    }
}

@ParameterizedTest
@ArgumentsSource(TestDefinition.Provider.class)
@TestDefinition(foo = "a", bar = "b")
@TestDefinition(foo = "c", bar = "d")
@TestDefinition(foo = "e", bar = "f")
void testImplementation(TestDefinition definition) {
    ...
}

The following is an easier means of reproducing; simply update the test harness in AnnotationConsumerInitializerTests to implement the deprecated method, instead of the new one:

diff --git a/jupiter-tests/src/test/java/org/junit/jupiter/params/support/AnnotationConsumerInitializerTests.java b/jupiter-tests/src/test/java/org/junit/jupiter/params/support/AnnotationConsumerInitializerTests.java
index 4d4ea67ecf..99aa940ec7 100644
--- a/jupiter-tests/src/test/java/org/junit/jupiter/params/support/AnnotationConsumerInitializerTests.java
+++ b/jupiter-tests/src/test/java/org/junit/jupiter/params/support/AnnotationConsumerInitializerTests.java
@@ -117,8 +117,8 @@ class AnnotationConsumerInitializerTests {
 		List<CsvSource> annotations = new ArrayList<>();
 
 		@Override
-		protected Stream<? extends Arguments> provideArguments(ParameterDeclarations parameters,
-				ExtensionContext context, CsvSource annotation) {
+		@SuppressWarnings("deprecation")
+		protected Stream<? extends Arguments> provideArguments(ExtensionContext context, CsvSource annotation) {
 			annotations.add(annotation);
 			return Stream.empty();
 		}

Upon running the tests in that suite, you will receive the following error:

Index 0 out of bounds for length 0
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at java.base@21.0.4/java.util.ImmutableCollections$ListN.get(ImmutableCollections.java:687)
	at app//org.junit.jupiter.params.support.AnnotationConsumerInitializer.findConsumedAnnotationType(AnnotationConsumerInitializer.java:78)
	at app//org.junit.jupiter.params.support.AnnotationConsumerInitializer.initialize(AnnotationConsumerInitializer.java:53)
	at app//org.junit.jupiter.params.support.AnnotationConsumerInitializerTests.shouldInitializeForEachAnnotations(AnnotationConsumerInitializerTests.java:110)
	at java.base@21.0.4/java.lang.reflect.Method.invoke(Method.java:580)
	at java.base@21.0.4/java.util.ArrayList.forEach(ArrayList.java:1596)
	at java.base@21.0.4/java.util.ArrayList.forEach(ArrayList.java:1596)

Context

  • Used versions (Jupiter/Vintage/Platform):
    • junit-bom 5.13.0
    • junit-jupiter-api
    • junit-vintage-engine
    • junit-platform-launcher
  • Build Tool/IDE:
    • Gradle 8.14.1

Proposed Solution

I believe that the issue stems from AnnotationConsumerInitializer#annotationConsumingMethodSignatures having been updated to only look for the new, non-deprecated method. Since the deprecated method is still present in production code, I think its signature should be present in that list:

diff --git a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java
index b6bdfd90f2..d80bbc0de7 100644
--- a/junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java
+++ b/junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java
@@ -40,6 +40,7 @@ public final class AnnotationConsumerInitializer {
 
 	private static final List<AnnotationConsumingMethodSignature> annotationConsumingMethodSignatures = asList( //
 		new AnnotationConsumingMethodSignature("accept", 1, 0), //
+		new AnnotationConsumingMethodSignature("provideArguments", 2, 1), //
 		new AnnotationConsumingMethodSignature("provideArguments", 3, 2), //
 		new AnnotationConsumingMethodSignature("convert", 3, 2));

In my limited testing, this resolved the issue I am seeing and kept compatibility with the behaviour in 5.13.0, but I'm not aware of the full scope of this change.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions