diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java index f24aa270733..4cb366668f8 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java @@ -282,7 +282,7 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes *
    *
  1. The {@linkplain ParameterContext#getDeclaringExecutable() declaring * executable} is a {@link Constructor} and - * {@link TestConstructorUtils#isAutowirableConstructor(Constructor, Class, PropertyProvider)} + * {@link TestConstructorUtils#isAutowirableConstructor(Executable, PropertyProvider)} * returns {@code true}. Note that {@code isAutowirableConstructor()} will be * invoked with a fallback {@link PropertyProvider} that delegates its lookup * to {@link ExtensionContext#getConfigurationParameter(String)}.
  2. @@ -296,17 +296,16 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes * constructor. Consequently, no other registered {@link ParameterResolver} * will be able to resolve parameters. * @see #resolveParameter - * @see TestConstructorUtils#isAutowirableConstructor(Constructor, Class) + * @see TestConstructorUtils#isAutowirableConstructor(Executable, PropertyProvider) * @see ParameterResolutionDelegate#isAutowirable */ @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { Parameter parameter = parameterContext.getParameter(); Executable executable = parameter.getDeclaringExecutable(); - Class testClass = extensionContext.getRequiredTestClass(); PropertyProvider junitPropertyProvider = propertyName -> extensionContext.getConfigurationParameter(propertyName).orElse(null); - return (TestConstructorUtils.isAutowirableConstructor(executable, testClass, junitPropertyProvider) || + return (TestConstructorUtils.isAutowirableConstructor(executable, junitPropertyProvider) || ApplicationContext.class.isAssignableFrom(parameter.getType()) || supportsApplicationEvents(parameterContext) || ParameterResolutionDelegate.isAutowirable(parameter, parameterContext.getIndex())); diff --git a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java index 506decf7ecf..f4cc44a8b26 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java @@ -78,6 +78,7 @@ public abstract class TestConstructorUtils { private TestConstructorUtils() { } + /** * Determine if the supplied executable for the given test class is an * autowirable constructor. @@ -86,8 +87,11 @@ public abstract class TestConstructorUtils { * @param executable an executable for the test class * @param testClass the test class * @return {@code true} if the executable is an autowirable constructor - * @see #isAutowirableConstructor(Executable, Class, PropertyProvider) + * @see #isAutowirableConstructor(Executable, PropertyProvider) + * @deprecated as of 6.2.13, in favor of {@link #isAutowirableConstructor(Executable, PropertyProvider)}; + * to be removed in Spring Framework 7.1 */ + @Deprecated(since = "6.2.13", forRemoval = true) public static boolean isAutowirableConstructor(Executable executable, Class testClass) { return isAutowirableConstructor(executable, testClass, null); } @@ -101,7 +105,10 @@ public abstract class TestConstructorUtils { * @param testClass the test class * @return {@code true} if the constructor is autowirable * @see #isAutowirableConstructor(Constructor, Class, PropertyProvider) + * @deprecated as of 6.2.13, in favor of {@link #isAutowirableConstructor(Executable, PropertyProvider)}; + * to be removed in Spring Framework 7.1 */ + @Deprecated(since = "6.2.13", forRemoval = true) public static boolean isAutowirableConstructor(Constructor constructor, Class testClass) { return isAutowirableConstructor(constructor, testClass, null); } @@ -119,7 +126,10 @@ public abstract class TestConstructorUtils { * @return {@code true} if the executable is an autowirable constructor * @since 5.3 * @see #isAutowirableConstructor(Constructor, Class, PropertyProvider) + * @deprecated as of 6.2.13, in favor of {@link #isAutowirableConstructor(Executable, PropertyProvider)}; + * to be removed in Spring Framework 7.1 */ + @Deprecated(since = "6.2.13", forRemoval = true) public static boolean isAutowirableConstructor(Executable executable, Class testClass, @Nullable PropertyProvider fallbackPropertyProvider) { @@ -148,16 +158,62 @@ public abstract class TestConstructorUtils { * {@link TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME}). *
* @param constructor a constructor for the test class - * @param testClass the test class + * @param testClass the test class, typically the declaring class of the constructor * @param fallbackPropertyProvider fallback property provider used to look up - * the value for the default test constructor autowire mode if no - * such value is found in {@link SpringProperties} + * the value for {@link TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME} + * if no such value is found in {@link SpringProperties}; may be {@code null} + * if there is no fallback support * @return {@code true} if the constructor is autowirable * @since 5.3 + * @see #isAutowirableConstructor(Executable, PropertyProvider) + * @deprecated as of 6.2.13, in favor of {@link #isAutowirableConstructor(Executable, PropertyProvider)}; + * to be removed in Spring Framework 7.1 */ + @Deprecated(since = "6.2.13", forRemoval = true) public static boolean isAutowirableConstructor(Constructor constructor, Class testClass, @Nullable PropertyProvider fallbackPropertyProvider) { + return isAutowirableConstructorInternal(constructor, testClass, fallbackPropertyProvider); + } + + /** + * Determine if the supplied {@link Executable} is an autowirable {@link Constructor}. + * + *

A constructor is considered to be autowirable if one of the following + * conditions is {@code true}. + * + *

    + *
  1. The constructor is annotated with {@link Autowired @Autowired}, + * {@link jakarta.inject.Inject @jakarta.inject.Inject}, or + * {@link javax.inject.Inject @javax.inject.Inject}.
  2. + *
  3. {@link TestConstructor @TestConstructor} is present or + * meta-present on the test class with + * {@link TestConstructor#autowireMode() autowireMode} set to + * {@link AutowireMode#ALL ALL}.
  4. + *
  5. The default test constructor autowire mode has been set to + * {@code ALL} in {@link SpringProperties} or in the supplied fallback + * {@link PropertyProvider}.
  6. + *
+ * @param executable an {@code Executable} for a test class + * @param fallbackPropertyProvider fallback property provider used to look up + * the value for {@value TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME} + * if no such value is found in {@link SpringProperties}; may be {@code null} + * if there is no fallback support + * @return {@code true} if the executable is an autowirable constructor + * @since 6.2.13 + * @see TestConstructor#TEST_CONSTRUCTOR_AUTOWIRE_MODE_PROPERTY_NAME + */ + public static boolean isAutowirableConstructor(Executable executable, + @Nullable PropertyProvider fallbackPropertyProvider) { + + return (executable instanceof Constructor constructor && + isAutowirableConstructorInternal(constructor, constructor.getDeclaringClass(), fallbackPropertyProvider)); + } + + + private static boolean isAutowirableConstructorInternal(Constructor constructor, Class testClass, + @Nullable PropertyProvider fallbackPropertyProvider) { + // Is the constructor annotated with @Autowired/@Inject? if (isAnnotatedWithAutowiredOrInject(constructor)) { return true; diff --git a/spring-test/src/test/java/org/springframework/test/context/support/TestConstructorUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/support/TestConstructorUtilsTests.java index 76cdbd4cd38..eda6d30d14d 100644 --- a/spring-test/src/test/java/org/springframework/test/context/support/TestConstructorUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/support/TestConstructorUtilsTests.java @@ -41,6 +41,9 @@ import static org.springframework.test.context.TestConstructor.AutowireMode.ANNO */ class TestConstructorUtilsTests { + private static final PropertyProvider propertyProvider = name -> null; + + @AfterEach void clearGlobalFlag() { setGlobalFlag(null); @@ -100,12 +103,12 @@ class TestConstructorUtilsTests { private void assertAutowirable(Class testClass) throws NoSuchMethodException { Constructor constructor = testClass.getDeclaredConstructor(); - assertThat(TestConstructorUtils.isAutowirableConstructor(constructor, testClass)).isTrue(); + assertThat(TestConstructorUtils.isAutowirableConstructor(constructor, propertyProvider)).isTrue(); } private void assertNotAutowirable(Class testClass) throws NoSuchMethodException { Constructor constructor = testClass.getDeclaredConstructor(); - assertThat(TestConstructorUtils.isAutowirableConstructor(constructor, testClass)).isFalse(); + assertThat(TestConstructorUtils.isAutowirableConstructor(constructor, propertyProvider)).isFalse(); } private void setGlobalFlag() {