Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Repeated @ExtendWith meta-annotations on fields no longer supported in 5.11.x #4054

Closed
ppkarwasz opened this issue Oct 7, 2024 · 5 comments

Comments

@ppkarwasz
Copy link

ppkarwasz commented Oct 7, 2024

Since version 5.11.x, if a field is meta-annotated with multiple @ExtendWith annotations, JUnit fails to detect them.

The problem seems to be in ExtensionUtils#streamExtensionFilteringFields, which does not take into account repeatable annotations:

private static Stream<Field> streamExtensionRegisteringFields(Class<?> clazz, Predicate<Field> predicate) {
Predicate<Field> composedPredicate = predicate.and(
field -> isAnnotated(field, ExtendWith.class) || isAnnotated(field, RegisterExtension.class));
return streamFields(clazz, composedPredicate, TOP_DOWN)//
.sorted(orderComparator);
}

Steps to reproduce

  1. Meta-annotate some test class fields with multiple @ExtendWith annotations:

    @Retention(RetentionPolicy.RUNTIME)
    @ExtendWith(Extension1.class)
    @ExtendWith(Extension2.class)
    public @interface ComposedAnnotation {}
    public class TestClassWithFields {
    
      @ComposedAnnotation
      private static int staticFieldMetaAnnotatedTwice;
    
      @ComposedAnnotation
      private int instanceFieldMetaAnnotatedTwice;
    }
  2. Run the following test cases:

    class ExtensionsUtilsTests {
      @Test
      void discoverExtensionsOnStaticFields() {
        ExtensionRegistrar registrar = mock();
        ExtensionUtils.registerExtensionsFromStaticFields(registrar, ClassWithFields.class);
        verify(registrar).registerExtension(Extension1.class);
        verify(registrar).registerExtension(Extension2.class);
      }
      @Test
      void discoverExtensionsOnInstanceFields() {
        ExtensionRegistrar registrar = mock();
        ExtensionUtils.registerExtensionsFromInstanceFields(registrar, ClassWithFields.class);
        verify(registrar).registerExtension(Extension1.class);
        verify(registrar).registerExtension(Extension2.class);
      }
    }

Context

  • Used versions (Jupiter/Vintage/Platform): Jupiter 5.11.1 / Platform 1.11.1
  • Build Tool/IDE: Maven
ppkarwasz added a commit to apache/logging-log4j2 that referenced this issue Oct 7, 2024
Due to a minor bug in JUnit 5.11.x (junit-team/junit5#4054), fields meta-annotated with multiple `@ExtendWith` annotations are no longer recognized.
We combine those annotations into single `@ExtendWith` annotations, which also looks better.

Closes #2843.
@marcphilipp marcphilipp self-assigned this Oct 8, 2024
@sbrannen
Copy link
Member

sbrannen commented Oct 8, 2024

Good catch, @ppkarwasz! 👍

The problem seems to be in ExtensionUtils#streamExtensionFilteringFields, which does not take into account repeatable annotations:

Indeed, the switch to the use of isAnnotated() there seems to be the culprit.

We'll work on a fix.

Cheers,

Sam

@marcphilipp
Copy link
Member

This was introduced in #3895

@sbrannen
Copy link
Member

sbrannen commented Oct 8, 2024

I've reproduced this in the following standalone test class, based on the examples from @ppkarwasz.

package org.junit.jupiter.engine.descriptor;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.engine.extension.ExtensionRegistrar;

class ExtensionsUtilsTests {

	@Test
	void discoverExtensionsOnStaticFields() {
		ExtensionRegistrar registrar = mock();
		ExtensionUtils.registerExtensionsFromStaticFields(registrar, TestClassWithFields.class);
		verify(registrar).registerExtension(Extension1.class);
		verify(registrar).registerExtension(Extension2.class);
	}

	@Test
	void discoverExtensionsOnInstanceFields() {
		ExtensionRegistrar registrar = mock();
		ExtensionUtils.registerExtensionsFromInstanceFields(registrar, TestClassWithFields.class);
		verify(registrar).registerExtension(Extension1.class);
		verify(registrar).registerExtension(Extension2.class);
	}

	static class Extension1 implements Extension {
	}

	static class Extension2 implements Extension {
	}

	@Retention(RetentionPolicy.RUNTIME)
	@ExtendWith(Extension1.class)
	@ExtendWith(Extension2.class)
	@interface UseCustomExtensions {
	}

	static class TestClassWithFields {

		@UseCustomExtensions
		static int staticFieldMetaAnnotatedTwice;

		@UseCustomExtensions
		int instanceFieldMetaAnnotatedTwice;

	}

}

@sbrannen sbrannen changed the title Registering multiple extensions on fields fails in version 5.11.x Repeated @ExtendWith annotations on fields no longer supported in 5.11.x Oct 8, 2024
@sbrannen sbrannen changed the title Repeated @ExtendWith annotations on fields no longer supported in 5.11.x Repeated @ExtendWith meta-annotations on fields no longer supported in 5.11.x Oct 8, 2024
sbrannen added a commit that referenced this issue Oct 8, 2024
JUnit Jupiter 5.11 introduced a regression regarding extension
registration via fields. Specifically, repeated @⁠ExtendWith
annotations on composed annotations were no longer found.

This commit fixes that regression by reintroducing support for finding
@⁠ExtendWith on custom composed annotations when @⁠ExtendWith is used
as a repeatable annotation.

Fixes #4054

(cherry picked from commit d274794)
@sbrannen
Copy link
Member

sbrannen commented Oct 8, 2024

This has been fixed on main and backported to 5.11.x for inclusion in 5.11.3.

@ppkarwasz
Copy link
Author

This has been fixed on main and backported to 5.11.x for inclusion in 5.11.3.

Wow, this was fast! Thank You!

ppkarwasz added a commit to apache/logging-log4j2 that referenced this issue Oct 10, 2024
Due to a minor bug in JUnit 5.11.x (junit-team/junit5#4054), fields meta-annotated with multiple `@ExtendWith` annotations are no longer recognized.
We combine those annotations into single `@ExtendWith` annotations, which also looks better.

Closes #2843.

Note: the bug is already fixed and the fix will appear in version `5.11.3`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants