From 41ae13df5d94d94207441d46224dcf5321fe8d5f Mon Sep 17 00:00:00 2001
From: Sam Brannen <104798+sbrannen@users.noreply.github.com>
Date: Thu, 23 Oct 2025 14:47:24 +0200
Subject: [PATCH] Use test-method scoped ExtensionContext in the
SpringExtension
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
As of Spring Framework 6.2.13, we support JUnit Jupiter 5.12's
ExtensionContextScope.TEST_METHOD behavior in the SpringExtension and
the BeanOverrideTestExecutionListener; however, users can only benefit
from that if they explicitly set the following configuration parameter
for their entire test suite, which may have adverse effects on other
third-party JUnit Jupiter extensions.
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method
For Spring Framework 7.0, in order to support dependency injection into
test class constructors and fields in @Nested test class hierarchies
from the same ApplicationContext that is already used to perform
dependency injection into lifecycle and test methods (@BeforeEach,
@AfterEach, @Test, etc.), we have decided to configure the
SpringExtension to use ExtensionContextScope.TEST_METHOD by default. In
addition, we have decided to provide a mechanism for users to switch
back to the legacy "test-class scoped ExtensionContext" behavior in
case third-party TestExecutionListener implementations are not yet
compatible with test-method scoped ExtensionContext and TestContext
semantics.
This commit achieves the above goals as follows.
- A new @SpringExtensionConfig annotation has been introduced, which
allows developers to configure the effective ExtensionContext scope
used by the SpringExtension.
- The SpringExtension now overrides
getTestInstantiationExtensionContextScope() to return
ExtensionContextScope.TEST_METHOD.
- The postProcessTestInstance() and resolveParameter() methods in the
SpringExtension now find the properly scoped ExtensionContext for the
supplied test class, based on whether the @Nested test class
hierarchy is annotated with
@SpringExtensionConfig(useTestClassScopedExtensionContext = true).
See gh-35680
See gh-35716
Closes gh-35697
---
.../test/context/ContextConfiguration.java | 2 +
.../test/context/NestedTestConfiguration.java | 3 +
.../test/context/TestConstructor.java | 1 +
.../test/context/TestContext.java | 1 +
.../test/context/TestExecutionListener.java | 1 +
.../junit/jupiter/SpringExtension.java | 116 +++++++-
.../junit/jupiter/SpringExtensionConfig.java | 68 +++++
.../junit/jupiter/SpringJUnitConfig.java | 9 +-
.../jupiter/web/SpringJUnitWebConfig.java | 11 +-
...copedExtensionContextIntegrationTests.java | 2 +
...copedExtensionContextIntegrationTests.java | 143 +++++-----
...copedExtensionContextIntegrationTests.java | 2 +
...copedExtensionContextIntegrationTests.java | 132 ++++-----
...copedExtensionContextIntegrationTests.java | 5 +-
...copedExtensionContextIntegrationTests.java | 77 ++----
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 143 +++++-----
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 136 ++++-----
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 149 +++++-----
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 146 +++++-----
...lassScopedExtensionContextNestedTests.java | 186 +++++++++++++
...thodScopedExtensionContextNestedTests.java | 184 +++++++++++++
...lassScopedExtensionContextNestedTests.java | 257 ++++++++++++++++++
...thodScopedExtensionContextNestedTests.java | 249 +++++++++++++++++
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 122 ++++-----
...lassScopedExtensionContextNestedTests.java | 2 +
...thodScopedExtensionContextNestedTests.java | 156 +++++------
.../orm/jpa/JpaPersonRepositoryTests.java | 67 ++---
32 files changed, 1632 insertions(+), 748 deletions(-)
create mode 100644 spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java
create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java
create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java
create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java
diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java
index e8ff6c0186d..cb07e6fef99 100644
--- a/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java
+++ b/spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java
@@ -80,6 +80,8 @@ import org.springframework.core.annotation.AliasFor;
*
* @author Sam Brannen
* @since 2.5
+ * @see org.springframework.test.context.junit.jupiter.SpringExtension SpringExtension
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
* @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
* @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
* @see ContextHierarchy @ContextHierarchy
diff --git a/spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java
index 05fb2b1cfee..fb4576ff181 100644
--- a/spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java
+++ b/spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java
@@ -95,6 +95,9 @@ import org.jspecify.annotations.Nullable;
*
{@link TestConstructor @TestConstructor}
*
*
+ * Note that {@code @NestedTestConfiguration} does not apply to
+ * {@link org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig}.
+ *
* @author Sam Brannen
* @since 5.3
* @see EnclosingConfiguration#INHERIT
diff --git a/spring-test/src/main/java/org/springframework/test/context/TestConstructor.java b/spring-test/src/main/java/org/springframework/test/context/TestConstructor.java
index 219c94cab8c..9803c83438b 100644
--- a/spring-test/src/main/java/org/springframework/test/context/TestConstructor.java
+++ b/spring-test/src/main/java/org/springframework/test/context/TestConstructor.java
@@ -61,6 +61,7 @@ import org.jspecify.annotations.Nullable;
* @see org.springframework.beans.factory.annotation.Autowired @Autowired
* @see jakarta.inject.Inject @jakarta.inject.Inject
* @see org.springframework.test.context.junit.jupiter.SpringExtension SpringExtension
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
* @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
* @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
* @see ContextConfiguration @ContextConfiguration
diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContext.java b/spring-test/src/main/java/org/springframework/test/context/TestContext.java
index 87816cadfcd..4cb97c5db5c 100644
--- a/spring-test/src/main/java/org/springframework/test/context/TestContext.java
+++ b/spring-test/src/main/java/org/springframework/test/context/TestContext.java
@@ -117,6 +117,7 @@ public interface TestContext extends AttributeAccessor, Serializable {
* invoke {@code testContext.getTestInstance().getClass()} instead of
* {@code testContext.getTestClass()}.
* @return the test class (never {@code null})
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
*/
Class> getTestClass();
diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java
index b9f9a96f4cc..81327908d9f 100644
--- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java
+++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java
@@ -169,6 +169,7 @@ public interface TestExecutionListener {
* concrete classes as necessary.
* @param testContext the test context for the test; never {@code null}
* @throws Exception allows any exception to propagate
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
*/
default void prepareTestInstance(TestContext testContext) throws Exception {
}
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 fb8c93a32fe..79869d8eb80 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
@@ -48,6 +48,7 @@ import org.junit.platform.commons.annotation.Testable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.ParameterResolutionDelegate;
import org.springframework.context.ApplicationContext;
+import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
import org.springframework.core.annotation.RepeatableContainers;
@@ -59,6 +60,8 @@ import org.springframework.test.context.event.RecordApplicationEvents;
import org.springframework.test.context.support.PropertyProvider;
import org.springframework.test.context.support.TestConstructorUtils;
import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ConcurrentLruCache;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodFilter;
@@ -66,18 +69,37 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
* {@code SpringExtension} integrates the Spring TestContext Framework
* into the JUnit Jupiter testing framework.
*
- *
To use this extension, simply annotate a JUnit Jupiter based test class with
- * {@code @ExtendWith(SpringExtension.class)}, {@code @SpringJUnitConfig}, or
- * {@code @SpringJUnitWebConfig}.
+ *
To use this extension, annotate a JUnit Jupiter based test class with
+ * {@code @ExtendWith(SpringExtension.class)}, {@code @SpringJUnitConfig},
+ * {@code @SpringJUnitWebConfig}, or any other annotation that is meta-annotated
+ * with {@code @ExtendWith(SpringExtension.class)} such as {@code @SpringBootTest},
+ * etc.
+ *
+ *
As of Spring Framework 7.0, the {@code SpringExtension} is
+ * {@linkplain #getTestInstantiationExtensionContextScope(ExtensionContext)
+ * configured} to use a test-method scoped {@link ExtensionContext}, which
+ * enables consistent dependency injection into fields and constructors from the
+ * {@link ApplicationContext} for the current test method in a
+ * {@link org.junit.jupiter.api.Nested @Nested} test class hierarchy. However,
+ * if a third-party {@link org.junit.platform.launcher.TestExecutionListener
+ * TestExecutionListener} is not compatible with the semantics associated with
+ * a test-method scoped extension context — or if a developer wishes to
+ * switch to test-class scoped semantics — the {@code SpringExtension} can
+ * be configured to use a test-class scoped extension context by annotating a
+ * top-level test class with
+ * {@link SpringExtensionConfig#useTestClassScopedExtensionContext()
+ * @SpringExtensionConfig(useTestClassScopedExtensionContext = true)}.
*
* @author Sam Brannen
* @author Simon Baslé
* @since 5.0
- * @see org.springframework.test.context.junit.jupiter.EnabledIf
- * @see org.springframework.test.context.junit.jupiter.DisabledIf
- * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig
- * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig
- * @see org.springframework.test.context.TestContextManager
+ * @see org.junit.jupiter.api.extension.ExtendWith @ExtendWith
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
+ * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
+ * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
+ * @see org.springframework.test.context.junit.jupiter.EnabledIf @EnabledIf
+ * @see org.springframework.test.context.junit.jupiter.DisabledIf @DisabledIf
+ * @see org.springframework.test.context.TestContextManager TestContextManager
*/
public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor,
BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback,
@@ -110,6 +132,14 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
private static final Namespace RECORD_APPLICATION_EVENTS_VALIDATION_NAMESPACE =
Namespace.create(SpringExtension.class.getName() + "#recordApplicationEvents.validation");
+ /**
+ * LRU cache for {@link SpringExtensionConfig#useTestClassScopedExtensionContext()}
+ * mappings, keyed by test class.
+ * @since 7.0
+ */
+ private static final ConcurrentLruCache, Boolean> useTestClassScopedExtensionContextCache =
+ new ConcurrentLruCache<>(32, SpringExtension::useTestClassScopedExtensionContext);
+
// Note that @Test, @TestFactory, @TestTemplate, @RepeatedTest, and @ParameterizedTest
// are all meta-annotated with @Testable.
private static final List> JUPITER_ANNOTATION_TYPES =
@@ -119,6 +149,19 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
ReflectionUtils.USER_DECLARED_METHODS.and(SpringExtension::isAutowiredTestOrLifecycleMethod);
+ /**
+ * Returns {@link ExtensionContextScope#TEST_METHOD ExtensionContextScope.TEST_METHOD}.
+ * This can be effectively overridden by annotating a test class with
+ * {@code @SpringExtensionConfig(useTestClassScopedExtensionContext = true)}.
+ * See the {@link SpringExtension class-level Javadoc} for further details.
+ * @since 7.0
+ * @see SpringExtensionConfig#useTestClassScopedExtensionContext()
+ */
+ @Override
+ public ExtensionContextScope getTestInstantiationExtensionContextScope(ExtensionContext rootContext) {
+ return ExtensionContextScope.TEST_METHOD;
+ }
+
/**
* Delegates to {@link TestContextManager#beforeTestClass}.
*/
@@ -151,6 +194,8 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
*/
@Override
public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {
+ context = findProperlyScopedExtensionContext(testInstance.getClass(), context);
+
validateAutowiredConfig(context);
validateRecordApplicationEventsConfig(context);
TestContextManager testContextManager = getTestContextManager(context);
@@ -332,7 +377,13 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
public @Nullable Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
Parameter parameter = parameterContext.getParameter();
int index = parameterContext.getIndex();
+ Executable executable = parameterContext.getDeclaringExecutable();
Class> testClass = extensionContext.getRequiredTestClass();
+ if (executable instanceof Constructor> constructor) {
+ testClass = constructor.getDeclaringClass();
+ extensionContext = findProperlyScopedExtensionContext(testClass, extensionContext);
+ }
+
ApplicationContext applicationContext = getApplicationContext(extensionContext);
return ParameterResolutionDelegate.resolveDependency(parameter, index, testClass,
applicationContext.getAutowireCapableBeanFactory());
@@ -390,4 +441,53 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes
return false;
}
+ /**
+ * Find the properly {@linkplain ExtensionContextScope scoped} {@link ExtensionContext}
+ * for the supplied test class.
+ *
If the supplied {@code ExtensionContext} is already properly scoped, it
+ * will be returned. Otherwise, if the test class is annotated with
+ * {@code @SpringExtensionConfig(useTestClassScopedExtensionContext = true)},
+ * this method searches the {@code ExtensionContext} hierarchy for an
+ * {@code ExtensionContext} whose test class is the same as the supplied
+ * test class.
+ * @since 7.0
+ * @see SpringExtensionConfig#useTestClassScopedExtensionContext()
+ * @see ExtensionContextScope
+ */
+ private static ExtensionContext findProperlyScopedExtensionContext(Class> testClass, ExtensionContext context) {
+ if (useTestClassScopedExtensionContextCache.get(testClass)) {
+ while (context.getRequiredTestClass() != testClass) {
+ context = context.getParent().get();
+ }
+ }
+ return context;
+ }
+
+ /**
+ * Determine if the supplied test class, or one of its enclosing classes, is annotated
+ * with {@code @SpringExtensionConfig(useTestClassScopedExtensionContext = true)}.
+ * @since 7.0
+ * @see SpringExtensionConfig#useTestClassScopedExtensionContext()
+ * @see #useTestClassScopedExtensionContextCache
+ */
+ private static boolean useTestClassScopedExtensionContext(Class> testClass) {
+ MergedAnnotation mergedAnnotation =
+ MergedAnnotations.search(SearchStrategy.TYPE_HIERARCHY)
+ .withEnclosingClasses(ClassUtils::isInnerClass)
+ .from(testClass)
+ .get(SpringExtensionConfig.class);
+
+ if (mergedAnnotation.isPresent()) {
+ if (mergedAnnotation.getSource() instanceof Class> source && ClassUtils.isInnerClass(source)) {
+ throw new IllegalStateException("""
+ Test class [%s] must not be annotated with @SpringExtensionConfig. \
+ @SpringExtensionConfig is only supported on top-level classes.\
+ """.formatted(source.getName()));
+ }
+ return mergedAnnotation.getBoolean("useTestClassScopedExtensionContext");
+ }
+
+ return false;
+ }
+
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java
new file mode 100644
index 00000000000..d7209e7654e
--- /dev/null
+++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * {@code @SpringExtensionConfig} is a type-level annotation that can be used to
+ * configure the behavior of the {@link SpringExtension}.
+ *
+ * This annotation is only applicable to {@link org.junit.jupiter.api.Nested @Nested}
+ * test class hierarchies and should be applied to the top-level enclosing class
+ * of a {@code @Nested} test class hierarchy. Consequently, there is no need to
+ * declare this annotation on a test class that does not contain {@code @Nested}
+ * test classes.
+ *
+ *
Note that
+ * {@link org.springframework.test.context.NestedTestConfiguration @NestedTestConfiguration}
+ * does not apply to this annotation: {@code @SpringExtensionConfig} will always be
+ * detected within a {@code @Nested} test class hierarchy, effectively disregarding
+ * any {@code @NestedTestConfiguration(OVERRIDE)} declarations.
+ *
+ * @author Sam Brannen
+ * @since 7.0
+ * @see org.springframework.test.context.junit.jupiter.SpringExtension SpringExtension
+ * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
+ * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface SpringExtensionConfig {
+
+ /**
+ * Specify whether the {@link SpringExtension} should use a test-class scoped
+ * {@link org.junit.jupiter.api.extension.ExtensionContext ExtensionContext}
+ * within {@link org.junit.jupiter.api.Nested @Nested} test class hierarchies.
+ *
+ *
By default, the {@code SpringExtension} uses a test-method scoped
+ * {@code ExtensionContext}. Thus, there is no need to declare this annotation
+ * attribute with a value of {@code false}.
+ *
+ * @see SpringExtension
+ * @see SpringExtension#getTestInstantiationExtensionContextScope(org.junit.jupiter.api.extension.ExtensionContext)
+ */
+ boolean useTestClassScopedExtensionContext();
+
+}
diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java
index 6e02a3380e6..0bb986c75f7 100644
--- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java
+++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java
@@ -42,10 +42,11 @@ import org.springframework.test.context.ContextLoader;
*
* @author Sam Brannen
* @since 5.0
- * @see ExtendWith
- * @see SpringExtension
- * @see ContextConfiguration
- * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig
+ * @see org.junit.jupiter.api.extension.ExtendWith @ExtendWith
+ * @see org.springframework.test.context.junit.jupiter.SpringExtension SpringExtension
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
+ * @see org.springframework.test.context.junit.ContextConfiguration @ContextConfiguration
+ * @see org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig @SpringJUnitWebConfig
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration
diff --git a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.java b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.java
index 4bba082fda8..30dd1d9860d 100644
--- a/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.java
+++ b/spring-test/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.java
@@ -45,11 +45,12 @@ import org.springframework.test.context.web.WebAppConfiguration;
*
* @author Sam Brannen
* @since 5.0
- * @see ExtendWith
- * @see SpringExtension
- * @see ContextConfiguration
- * @see WebAppConfiguration
- * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig
+ * @see org.junit.jupiter.api.extension.ExtendWith @ExtendWith
+ * @see org.springframework.test.context.junit.jupiter.SpringExtension SpringExtension
+ * @see org.springframework.test.context.junit.jupiter.SpringExtensionConfig @SpringExtensionConfig
+ * @see org.springframework.test.context.junit.ContextConfiguration @ContextConfiguration
+ * @see org.springframework.test.context.web.WebAppConfiguration @WebAppConfiguration
+ * @see org.springframework.test.context.junit.jupiter.SpringJUnitConfig @SpringJUnitConfig
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
index 6eba56e7bfb..660fcde7ed6 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
@@ -26,6 +26,7 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 6.2
*/
@SpringJUnitConfig
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
public class TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@TestBean(name = "field")
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
index 2b41f116f46..64a22a09945 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -28,10 +27,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
-
/**
* Integration tests for {@link TestBean} that use by-name lookup with
@@ -41,35 +36,46 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig
public class TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
+ @TestBean(name = "field")
+ String field;
+
+ @TestBean(name = "methodRenamed1", methodName = "field")
+ String methodRenamed1;
+
+ static String field() {
+ return "fieldOverride";
+ }
+
+ static String nestedField() {
+ return "nestedFieldOverride";
+ }
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(12).succeeded(12).failed(0));
+ void fieldHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
+ assertThat(field).as("injection point").isEqualTo("fieldOverride");
}
+ @Test
+ void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
+ assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
+ }
- @SpringJUnitConfig
- public static class TestCase {
- @TestBean(name = "field")
- String field;
+ @Nested
+ @DisplayName("With @TestBean in enclosing class and in @Nested class")
+ public class TestBeanFieldInEnclosingClassTests {
- @TestBean(name = "methodRenamed1", methodName = "field")
- String methodRenamed1;
+ @TestBean(name = "nestedField")
+ String nestedField;
- static String field() {
- return "fieldOverride";
- }
+ @TestBean(name = "methodRenamed2", methodName = "nestedField")
+ String methodRenamed2;
- static String nestedField() {
- return "nestedFieldOverride";
- }
@Test
void fieldHasOverride(ApplicationContext ctx) {
@@ -83,17 +89,21 @@ public class TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTest
assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
}
+ @Test
+ void nestedFieldHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
+ assertThat(nestedField).isEqualTo("nestedFieldOverride");
+ }
- @Nested
- @DisplayName("With @TestBean in enclosing class and in @Nested class")
- public class TestBeanFieldInEnclosingClassTestCase {
-
- @TestBean(name = "nestedField")
- String nestedField;
-
- @TestBean(name = "methodRenamed2", methodName = "nestedField")
- String methodRenamed2;
+ @Test
+ void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
+ assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
+ }
+ @Nested
+ @DisplayName("With @TestBean in the enclosing classes")
+ public class TestBeanFieldInEnclosingClassLevel2Tests {
@Test
void fieldHasOverride(ApplicationContext ctx) {
@@ -118,62 +128,33 @@ public class TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTest
assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
}
+ }
+ }
- @Nested
- @DisplayName("With @TestBean in the enclosing classes")
- public class TestBeanFieldInEnclosingClassLevel2TestCase {
-
- @Test
- void fieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("field")).as("applicationContext").isEqualTo("fieldOverride");
- assertThat(field).as("injection point").isEqualTo("fieldOverride");
- }
-
- @Test
- void fieldWithMethodNameHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("methodRenamed1")).as("applicationContext").isEqualTo("fieldOverride");
- assertThat(methodRenamed1).as("injection point").isEqualTo("fieldOverride");
- }
-
- @Test
- void nestedFieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
- assertThat(nestedField).isEqualTo("nestedFieldOverride");
- }
-
- @Test
- void nestedFieldWithMethodNameHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("methodRenamed2")).as("applicationContext").isEqualTo("nestedFieldOverride");
- assertThat(methodRenamed2).isEqualTo("nestedFieldOverride");
- }
- }
+ @Nested
+ @DisplayName("With factory method in enclosing class")
+ public class TestBeanFactoryMethodInEnclosingClassTests {
+
+ @TestBean(methodName = "nestedField", name = "nestedField")
+ String nestedField;
+
+ @Test
+ void nestedFieldHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
+ assertThat(nestedField).isEqualTo("nestedFieldOverride");
}
@Nested
- @DisplayName("With factory method in enclosing class")
- public class TestBeanFactoryMethodInEnclosingClassTestCase {
+ @DisplayName("With factory method in the enclosing class of the enclosing class")
+ public class TestBeanFactoryMethodInEnclosingClassLevel2Tests {
- @TestBean(methodName = "nestedField", name = "nestedField")
- String nestedField;
+ @TestBean(methodName = "nestedField", name = "nestedNestedField")
+ String nestedNestedField;
@Test
void nestedFieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("nestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
- assertThat(nestedField).isEqualTo("nestedFieldOverride");
- }
-
- @Nested
- @DisplayName("With factory method in the enclosing class of the enclosing class")
- public class TestBeanFactoryMethodInEnclosingClassLevel2TestCase {
-
- @TestBean(methodName = "nestedField", name = "nestedNestedField")
- String nestedNestedField;
-
- @Test
- void nestedFieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("nestedNestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
- assertThat(nestedNestedField).isEqualTo("nestedFieldOverride");
- }
+ assertThat(ctx.getBean("nestedNestedField")).as("applicationContext").isEqualTo("nestedFieldOverride");
+ assertThat(nestedNestedField).isEqualTo("nestedFieldOverride");
}
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
index 0ff4d3d5df8..03345c3c231 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
@@ -30,6 +30,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.RealExampleService;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
@@ -44,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 6.2
*/
@SpringJUnitConfig
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
public class MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@MockitoBean("field")
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
index e2c5986d948..70310538847 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -33,9 +32,6 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
/**
* Integration tests for {@link MockitoBean} that use by-name lookup with
@@ -45,27 +41,54 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig
public class MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
+ @MockitoBean("field")
+ ExampleService field;
+
+ @MockitoBean("nonExistingBean")
+ ExampleService nonExisting;
+
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(6).succeeded(6).failed(0));
+ void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("field"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsMock)
+ .isSameAs(field);
+
+ assertThat(field.greeting()).as("mocked greeting").isNull();
}
+ @Test
+ void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
+ assertThat(ctx.getBean("nonExistingBean"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsMock)
+ .isSameAs(nonExisting);
+
+ assertThat(nonExisting.greeting()).as("mocked greeting").isNull();
+ }
+
+
+ @Nested
+ @DisplayName("With @MockitoBean in enclosing class and in @Nested class")
+ public class MockitoBeanNestedTests {
- @SpringJUnitConfig
- public static class TestCase {
+ @Autowired
+ @Qualifier("field")
+ ExampleService localField;
- @MockitoBean("field")
- ExampleService field;
+ @Autowired
+ @Qualifier("nonExistingBean")
+ ExampleService localNonExisting;
- @MockitoBean("nonExistingBean")
- ExampleService nonExisting;
+ @MockitoBean("nestedField")
+ ExampleService nestedField;
+
+ @MockitoBean("nestedNonExistingBean")
+ ExampleService nestedNonExisting;
@Test
@@ -73,9 +96,9 @@ public class MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationT
assertThat(ctx.getBean("field"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(field);
+ .isSameAs(localField);
- assertThat(field.greeting()).as("mocked greeting").isNull();
+ assertThat(localField.greeting()).as("mocked greeting").isNull();
}
@Test
@@ -83,66 +106,25 @@ public class MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationT
assertThat(ctx.getBean("nonExistingBean"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(nonExisting);
+ .isSameAs(localNonExisting);
- assertThat(nonExisting.greeting()).as("mocked greeting").isNull();
+ assertThat(localNonExisting.greeting()).as("mocked greeting").isNull();
}
+ @Test
+ void nestedFieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("nestedField"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsMock)
+ .isSameAs(nestedField);
+ }
- @Nested
- @DisplayName("With @MockitoBean in enclosing class and in @Nested class")
- public class MockitoBeanNestedTestCase {
-
- @Autowired
- @Qualifier("field")
- ExampleService localField;
-
- @Autowired
- @Qualifier("nonExistingBean")
- ExampleService localNonExisting;
-
- @MockitoBean("nestedField")
- ExampleService nestedField;
-
- @MockitoBean("nestedNonExistingBean")
- ExampleService nestedNonExisting;
-
-
- @Test
- void fieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("field"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(localField);
-
- assertThat(localField.greeting()).as("mocked greeting").isNull();
- }
-
- @Test
- void fieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
- assertThat(ctx.getBean("nonExistingBean"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(localNonExisting);
-
- assertThat(localNonExisting.greeting()).as("mocked greeting").isNull();
- }
-
- @Test
- void nestedFieldAndRenamedFieldHaveSameOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("nestedField"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(nestedField);
- }
-
- @Test
- void nestedFieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
- assertThat(ctx.getBean("nestedNonExistingBean"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsMock)
- .isSameAs(nestedNonExisting);
- }
+ @Test
+ void nestedFieldIsMockedWhenNoOriginalBean(ApplicationContext ctx) {
+ assertThat(ctx.getBean("nestedNonExistingBean"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsMock)
+ .isSameAs(nestedNonExisting);
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
index 49dc19acab2..6924ba66a5e 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
@@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.bean.override.example.ExampleService;
import org.springframework.test.context.bean.override.example.RealExampleService;
-import org.springframework.test.context.bean.override.mockito.MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.Config;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
@@ -44,7 +44,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Sam Brannen
* @since 6.2
*/
-@SpringJUnitConfig(Config.class)
+@SpringJUnitConfig
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
public class MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@MockitoSpyBean("field1")
diff --git a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
index 6aa660a9f5f..6e8e35d195a 100644
--- a/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -33,9 +32,6 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.mockito.MockitoAssertions;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
/**
* Integration tests for {@link MockitoSpyBean} that use by-name lookup with
@@ -45,70 +41,57 @@ import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig
public class MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests {
+ @MockitoSpyBean("field1")
+ ExampleService field;
+
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(3).succeeded(3).failed(0));
+ void fieldHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("field1"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsSpy)
+ .isSameAs(field);
+
+ assertThat(field.greeting()).isEqualTo("bean1");
}
- @SpringJUnitConfig(Config.class)
- public static class TestCase {
+ @Nested
+ @DisplayName("With @MockitoSpyBean in enclosing class and in @Nested class")
+ public class MockitoSpyBeanNestedTests {
- @MockitoSpyBean("field1")
- ExampleService field;
+ @Autowired
+ @Qualifier("field1")
+ ExampleService localField;
+ @MockitoSpyBean("field2")
+ ExampleService nestedField;
@Test
void fieldHasOverride(ApplicationContext ctx) {
assertThat(ctx.getBean("field1"))
.isInstanceOf(ExampleService.class)
.satisfies(MockitoAssertions::assertIsSpy)
- .isSameAs(field);
+ .isSameAs(localField);
- assertThat(field.greeting()).isEqualTo("bean1");
+ assertThat(localField.greeting()).isEqualTo("bean1");
}
+ @Test
+ void nestedFieldHasOverride(ApplicationContext ctx) {
+ assertThat(ctx.getBean("field2"))
+ .isInstanceOf(ExampleService.class)
+ .satisfies(MockitoAssertions::assertIsSpy)
+ .isSameAs(nestedField);
- @Nested
- @DisplayName("With @MockitoSpyBean in enclosing class and in @Nested class")
- public class MockitoSpyBeanNestedTestCase {
-
- @Autowired
- @Qualifier("field1")
- ExampleService localField;
-
- @MockitoSpyBean("field2")
- ExampleService nestedField;
-
- @Test
- void fieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("field1"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsSpy)
- .isSameAs(localField);
-
- assertThat(localField.greeting()).isEqualTo("bean1");
- }
-
- @Test
- void nestedFieldHasOverride(ApplicationContext ctx) {
- assertThat(ctx.getBean("field2"))
- .isInstanceOf(ExampleService.class)
- .satisfies(MockitoAssertions::assertIsSpy)
- .isSameAs(nestedField);
-
- assertThat(nestedField.greeting()).isEqualTo("bean2");
- }
+ assertThat(nestedField.greeting()).isEqualTo("bean2");
}
}
+
@Configuration(proxyBeanMethods = false)
static class Config {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java
index ce83b45a1f5..c106a554701 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java
@@ -30,6 +30,7 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ActiveProfilesTestClassScopedExtensionContextNestedTests.Config1;
@@ -47,6 +48,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @since 5.3
*/
@SpringJUnitConfig(Config1.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@ActiveProfiles("1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ActiveProfilesTestClassScopedExtensionContextNestedTests {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java
index a8a73be4183..cff8e4072d5 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java
@@ -21,7 +21,6 @@ import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -32,11 +31,9 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ActiveProfilesTestMethodScopedExtensionContextNestedTests.Config1;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
@@ -49,72 +46,77 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig(Config1.class)
+@ActiveProfiles("1")
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ActiveProfilesTestMethodScopedExtensionContextNestedTests {
+ @Autowired
+ List strings;
+
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(7).succeeded(7).failed(0));
+ void test() {
+ assertThat(this.strings).containsExactlyInAnyOrder("X", "A1");
}
- @SpringJUnitConfig(Config1.class)
- @ActiveProfiles("1")
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- static class TestCase {
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class InheritedConfigTests {
@Autowired
- List strings;
+ List localStrings;
@Test
void test() {
- assertThat(this.strings).containsExactlyInAnyOrder("X", "A1");
+ assertThat(strings)
+ .isEqualTo(this.localStrings)
+ .containsExactlyInAnyOrder("X", "A1");
}
+ }
+ @Nested
+ @SpringJUnitConfig(Config2.class)
+ @ActiveProfiles("2")
+ class ConfigOverriddenByDefaultTests {
- @Nested
- @NestedTestConfiguration(INHERIT)
- class InheritedConfigTestCase {
-
- @Autowired
- List localStrings;
+ @Autowired
+ List localStrings;
- @Test
- void test() {
- assertThat(strings)
- .isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("X", "A1");
- }
+ @Test
+ void test() {
+ assertThat(strings)
+ .isEqualTo(this.localStrings)
+ .containsExactlyInAnyOrder("Y", "A2");
}
+ }
- @Nested
- @SpringJUnitConfig(Config2.class)
- @ActiveProfiles("2")
- class ConfigOverriddenByDefaultTestCase {
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ @ContextConfiguration(classes = Config2.class)
+ @ActiveProfiles("2")
+ class InheritedAndExtendedConfigTests {
- @Autowired
- List localStrings;
+ @Autowired
+ List localStrings;
- @Test
- void test() {
- assertThat(strings)
- .isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("Y", "A2");
- }
+ @Test
+ void test() {
+ assertThat(strings)
+ .isEqualTo(this.localStrings)
+ .containsExactlyInAnyOrder("X", "A1", "Y", "A2");
}
+
@Nested
- @NestedTestConfiguration(INHERIT)
- @ContextConfiguration(classes = Config2.class)
- @ActiveProfiles("2")
- class InheritedAndExtendedConfigTestCase {
+ @NestedTestConfiguration(OVERRIDE)
+ @SpringJUnitConfig({ Config1.class, Config2.class, Config3.class })
+ @ActiveProfiles("3")
+ class DoubleNestedWithOverriddenConfigTests {
@Autowired
List localStrings;
@@ -124,15 +126,14 @@ class ActiveProfilesTestMethodScopedExtensionContextNestedTests {
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("X", "A1", "Y", "A2");
+ .containsExactlyInAnyOrder("X", "Y", "Z", "A3");
}
@Nested
- @NestedTestConfiguration(OVERRIDE)
- @SpringJUnitConfig({ Config1.class, Config2.class, Config3.class })
- @ActiveProfiles("3")
- class DoubleNestedWithOverriddenConfigTestCase {
+ @NestedTestConfiguration(INHERIT)
+ @ActiveProfiles(profiles = "2", inheritProfiles = false)
+ class TripleNestedWithInheritedConfigButOverriddenProfilesTests {
@Autowired
List localStrings;
@@ -142,41 +143,23 @@ class ActiveProfilesTestMethodScopedExtensionContextNestedTests {
void test() {
assertThat(strings)
.isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("X", "Y", "Z", "A3");
- }
-
-
- @Nested
- @NestedTestConfiguration(INHERIT)
- @ActiveProfiles(profiles = "2", inheritProfiles = false)
- class TripleNestedWithInheritedConfigButOverriddenProfilesTestCase {
-
- @Autowired
- List localStrings;
-
-
- @Test
- void test() {
- assertThat(strings)
- .isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("X", "Y", "Z", "A2");
- }
+ .containsExactlyInAnyOrder("X", "Y", "Z", "A2");
}
+ }
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
- @Autowired
- List localStrings;
+ @Autowired
+ List localStrings;
- @Test
- void test() {
- assertThat(strings)
- .isEqualTo(this.localStrings)
- .containsExactlyInAnyOrder("X", "Y", "Z", "A2", "A3");
- }
+ @Test
+ void test() {
+ assertThat(strings)
+ .isEqualTo(this.localStrings)
+ .containsExactlyInAnyOrder("X", "Y", "Z", "A2", "A3");
}
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java
index 81cf6117107..fbd29e7553d 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java
@@ -28,6 +28,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ConstructorInjectionTestClassScopedExtensionContextNestedTests.TopLevelConfig;
@@ -46,6 +47,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
@SpringJUnitConfig(TopLevelConfig.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ConstructorInjectionTestClassScopedExtensionContextNestedTests {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
index b6ba04cd91a..5882ed52867 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -30,11 +29,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ConstructorInjectionTestMethodScopedExtensionContextNestedTests.TopLevelConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
/**
@@ -48,106 +45,91 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @see ContextConfigurationTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
+@SpringJUnitConfig(TopLevelConfig.class)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ConstructorInjectionTestMethodScopedExtensionContextNestedTests {
- @Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(5).succeeded(5).failed(0));
+ final String foo;
+
+ ConstructorInjectionTestMethodScopedExtensionContextNestedTests(TestInfo testInfo, @Autowired String foo) {
+ this.foo = foo;
}
+ @Test
+ void topLevelTest() {
+ assertThat(foo).isEqualTo("foo");
+ }
- @SpringJUnitConfig(TopLevelConfig.class)
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- static class TestCase {
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorTests {
- final String foo;
+ final String bar;
- TestCase(TestInfo testInfo, @Autowired String foo) {
- this.foo = foo;
+ @Autowired
+ AutowiredConstructorTests(String bar) {
+ this.bar = bar;
}
@Test
- void topLevelTest() {
- assertThat(foo).isEqualTo("foo");
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
}
+ }
- @Nested
- @SpringJUnitConfig(NestedConfig.class)
- class AutowiredConstructorTestCase {
-
- final String bar;
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorParameterTests {
- @Autowired
- AutowiredConstructorTestCase(String bar) {
- this.bar = bar;
- }
+ final String bar;
- @Test
- void nestedTest() {
- assertThat(foo).isEqualTo("bar");
- assertThat(bar).isEqualTo("bar");
- }
+ AutowiredConstructorParameterTests(@Autowired String bar) {
+ this.bar = bar;
}
- @Nested
- @SpringJUnitConfig(NestedConfig.class)
- class AutowiredConstructorParameterTestCase {
-
- final String bar;
-
- AutowiredConstructorParameterTestCase(@Autowired String bar) {
- this.bar = bar;
- }
-
- @Test
- void nestedTest() {
- assertThat(foo).isEqualTo("bar");
- assertThat(bar).isEqualTo("bar");
- }
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
}
+ }
- @Nested
- @SpringJUnitConfig(NestedConfig.class)
- class QualifiedConstructorParameterTestCase {
-
- final String bar;
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class QualifiedConstructorParameterTests {
- QualifiedConstructorParameterTestCase(TestInfo testInfo, @Qualifier("bar") String s) {
- this.bar = s;
- }
+ final String bar;
- @Test
- void nestedTest() {
- assertThat(foo).isEqualTo("bar");
- assertThat(bar).isEqualTo("bar");
- }
+ QualifiedConstructorParameterTests(TestInfo testInfo, @Qualifier("bar") String s) {
+ this.bar = s;
}
- @Nested
- @SpringJUnitConfig(NestedConfig.class)
- class SpelConstructorParameterTestCase {
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ }
+ }
- final String bar;
- final int answer;
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class SpelConstructorParameterTests {
- SpelConstructorParameterTestCase(@Autowired String bar, TestInfo testInfo, @Value("#{ 6 * 7 }") int answer) {
- this.bar = bar;
- this.answer = answer;
- }
+ final String bar;
+ final int answer;
- @Test
- void nestedTest() {
- assertThat(foo).isEqualTo("bar");
- assertThat(bar).isEqualTo("bar");
- assertThat(answer).isEqualTo(42);
- }
+ SpelConstructorParameterTests(@Autowired String bar, TestInfo testInfo, @Value("#{ 6 * 7 }") int answer) {
+ this.bar = bar;
+ this.answer = answer;
}
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ assertThat(answer).isEqualTo(42);
+ }
}
// -------------------------------------------------------------------------
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java
index 34bbcc3bec6..607a2190fcc 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java
@@ -27,6 +27,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.test.context.junit.jupiter.nested.ContextConfigurationTestClassScopedExtensionContextNestedTests.TopLevelConfig;
@@ -46,6 +47,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
@SpringJUnitConfig(TopLevelConfig.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ContextConfigurationTestClassScopedExtensionContextNestedTests {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestMethodScopedExtensionContextNestedTests.java
index fecf82498ab..2d1a35b02c6 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestMethodScopedExtensionContextNestedTests.java
@@ -19,7 +19,6 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -29,11 +28,9 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ContextConfigurationTestMethodScopedExtensionContextNestedTests.TopLevelConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
@@ -48,46 +45,72 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @see ConstructorInjectionTestClassScopedExtensionContextNestedTests
* @see org.springframework.test.context.junit4.nested.NestedTestsWithSpringRulesTests
*/
+@SpringJUnitConfig(TopLevelConfig.class)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class ContextConfigurationTestMethodScopedExtensionContextNestedTests {
private static final String FOO = "foo";
private static final String BAR = "bar";
private static final String BAZ = "baz";
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String foo;
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(6).succeeded(6).failed(0));
+ void topLevelTest() {
+ assertThat(foo).isEqualTo(FOO);
}
- @SpringJUnitConfig(TopLevelConfig.class)
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- static class TestCase {
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class NestedTests {
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
- private static final String FOO = "foo";
- private static final String BAR = "bar";
- private static final String BAZ = "baz";
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ }
+ }
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class NestedTestsWithInheritedConfigTests {
@Autowired(required = false)
@Qualifier("foo")
- String foo;
+ String localFoo;
+
+ @Autowired
+ String bar;
@Test
- void topLevelTest() {
+ void test() {
+ // Since the configuration is inherited, the foo field in the outer instance
+ // and the bar field in the inner instance should both have been injected
+ // from the test ApplicationContext for the outer instance.
assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).isEqualTo(FOO);
+ assertThat(this.bar).isEqualTo(FOO);
}
@Nested
+ @NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(NestedConfig.class)
- class NestedTestCase {
+ class DoubleNestedWithOverriddenConfigTests {
@Autowired(required = false)
@Qualifier("foo")
@@ -103,35 +126,11 @@ class ContextConfigurationTestMethodScopedExtensionContextNestedTests {
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
}
- }
-
- @Nested
- @NestedTestConfiguration(INHERIT)
- class NestedTestCaseWithInheritedConfigTestCase {
-
- @Autowired(required = false)
- @Qualifier("foo")
- String localFoo;
-
- @Autowired
- String bar;
-
-
- @Test
- void test() {
- // Since the configuration is inherited, the foo field in the outer instance
- // and the bar field in the inner instance should both have been injected
- // from the test ApplicationContext for the outer instance.
- assertThat(foo).isEqualTo(FOO);
- assertThat(this.localFoo).isEqualTo(FOO);
- assertThat(this.bar).isEqualTo(FOO);
- }
@Nested
- @NestedTestConfiguration(OVERRIDE)
- @SpringJUnitConfig(NestedConfig.class)
- class DoubleNestedWithOverriddenConfigTestCase {
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigTests {
@Autowired(required = false)
@Qualifier("foo")
@@ -147,55 +146,33 @@ class ContextConfigurationTestMethodScopedExtensionContextNestedTests {
assertThat(this.localFoo).as("local foo bean should not be present").isNull();
assertThat(this.bar).isEqualTo(BAR);
}
+ }
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedWithInheritedConfigTestCase {
-
- @Autowired(required = false)
- @Qualifier("foo")
- String localFoo;
-
- @Autowired
- String bar;
-
-
- @Test
- void test() {
- assertThat(foo).as("foo bean should not be present").isNull();
- assertThat(this.localFoo).as("local foo bean should not be present").isNull();
- assertThat(this.bar).isEqualTo(BAR);
- }
- }
-
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
-
- @Autowired(required = false)
- @Qualifier("foo")
- String localFoo;
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
- @Autowired
- @Qualifier("bar")
- String bar;
+ @Autowired
+ @Qualifier("bar")
+ String bar;
- @Autowired
- String baz;
+ @Autowired
+ String baz;
- @Test
- void test() {
- assertThat(foo).as("foo bean should not be present").isNull();
- assertThat(this.localFoo).as("local foo bean should not be present").isNull();
- assertThat(this.bar).isEqualTo(BAR);
- assertThat(this.baz).isEqualTo(BAZ);
- }
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ assertThat(this.baz).isEqualTo(BAZ);
}
}
}
-
}
// -------------------------------------------------------------------------
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java
index c47cf2a630b..399b09584b2 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java
@@ -31,6 +31,7 @@ import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.aot.DisabledInAotMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.nested.ContextHierarchyTestClassScopedExtensionContextNestedTests.ParentConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -47,6 +48,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @since 5.3
*/
@ExtendWith(SpringExtension.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@ContextHierarchy(@ContextConfiguration(classes = ParentConfig.class))
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
@DisabledInAotMode("@ContextHierarchy is not supported in AOT")
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java
index dfc0777c33d..1efd1b4812c 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java
@@ -20,7 +20,6 @@ import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -32,11 +31,9 @@ import org.springframework.test.context.ContextHierarchy;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.aot.DisabledInAotMode;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.nested.ContextHierarchyTestMethodScopedExtensionContextNestedTests.ParentConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
@@ -49,6 +46,10 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @author Sam Brannen
* @since 6.2.13
*/
+@ExtendWith(SpringExtension.class)
+@ContextHierarchy(@ContextConfiguration(classes = ParentConfig.class))
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
+@DisabledInAotMode("@ContextHierarchy is not supported in AOT")
class ContextHierarchyTestMethodScopedExtensionContextNestedTests {
private static final String FOO = "foo";
@@ -57,65 +58,77 @@ class ContextHierarchyTestMethodScopedExtensionContextNestedTests {
private static final String QUX = "qux";
+ @Autowired
+ String foo;
+
+ @Autowired
+ ApplicationContext context;
+
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(5).succeeded(5).failed(0));
- }
+ void topLevelTest() {
+ assertThat(this.context).as("local ApplicationContext").isNotNull();
+ assertThat(this.context.getParent()).as("parent ApplicationContext").isNull();
+ assertThat(foo).isEqualTo(FOO);
+ }
- @ExtendWith(SpringExtension.class)
- @ContextHierarchy(@ContextConfiguration(classes = ParentConfig.class))
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- @DisabledInAotMode("@ContextHierarchy is not supported in AOT")
- static class TestCase {
+ @Nested
+ @ContextConfiguration(classes = NestedConfig.class)
+ class NestedTests {
@Autowired
- String foo;
+ String bar;
@Autowired
ApplicationContext context;
@Test
- void topLevelTest() {
+ void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNull();
- assertThat(foo).isEqualTo(FOO);
+ // The foo field in the outer instance should have been injected from
+ // the test ApplicationContext for NestedTests.
+ assertThat(foo).isEqualTo(BAR);
+ assertThat(this.bar).isEqualTo(BAR);
}
+ }
- @Nested
- @ContextConfiguration(classes = NestedConfig.class)
- class NestedTestCase {
-
- @Autowired
- String bar;
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ @ContextConfiguration(classes = Child1Config.class)
+ class NestedInheritedCfgTests {
- @Autowired
- ApplicationContext context;
+ @Autowired
+ String bar;
+ @Autowired
+ ApplicationContext context;
- @Test
- void nestedTest() {
- assertThat(this.context).as("local ApplicationContext").isNotNull();
- assertThat(this.context.getParent()).as("parent ApplicationContext").isNull();
- // The foo field in the outer instance should have been injected from
- // the test ApplicationContext for NestedTestCase.
- assertThat(foo).isEqualTo(BAR);
- assertThat(this.bar).isEqualTo(BAR);
- }
+ @Test
+ void nestedTest() {
+ assertThat(this.context).as("local ApplicationContext").isNotNull();
+ assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
+
+ // The foo field in the outer instance and the bar field in the inner
+ // instance should both have been injected from the test ApplicationContext
+ // for the inner instance.
+ assertThat(foo).as("foo")
+ .isEqualTo(this.context.getBean("foo", String.class))
+ .isEqualTo(QUX + 1);
+ assertThat(this.bar).isEqualTo(BAZ + 1);
}
@Nested
- @NestedTestConfiguration(INHERIT)
- @ContextConfiguration(classes = Child1Config.class)
- class NestedInheritedCfgTestCase {
+ @NestedTestConfiguration(OVERRIDE)
+ @ContextHierarchy({
+ @ContextConfiguration(classes = ParentConfig.class),
+ @ContextConfiguration(classes = Child2Config.class)
+ })
+ class DoubleNestedOverriddenCfgTests {
@Autowired
String bar;
@@ -129,22 +142,19 @@ class ContextHierarchyTestMethodScopedExtensionContextNestedTests {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
- // The foo field in the outer instance and the bar field in the inner
- // instance should both have been injected from the test ApplicationContext
- // for the inner instance.
assertThat(foo).as("foo")
.isEqualTo(this.context.getBean("foo", String.class))
- .isEqualTo(QUX + 1);
- assertThat(this.bar).isEqualTo(BAZ + 1);
+ .isEqualTo(QUX + 2);
+ assertThat(this.bar).isEqualTo(BAZ + 2);
}
@Nested
- @NestedTestConfiguration(OVERRIDE)
- @ContextHierarchy({
- @ContextConfiguration(classes = ParentConfig.class),
- @ContextConfiguration(classes = Child2Config.class)
- })
- class DoubleNestedOverriddenCfgTestCase {
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedInheritedCfgAndTestInterfaceTests implements TestInterface {
+
+ @Autowired
+ @Qualifier("foo")
+ String localFoo;
@Autowired
String bar;
@@ -157,44 +167,16 @@ class ContextHierarchyTestMethodScopedExtensionContextNestedTests {
void nestedTest() {
assertThat(this.context).as("local ApplicationContext").isNotNull();
assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
+ assertThat(this.context.getParent().getParent()).as("grandparent ApplicationContext").isNotNull();
assertThat(foo).as("foo")
+ .isEqualTo(this.localFoo)
.isEqualTo(this.context.getBean("foo", String.class))
- .isEqualTo(QUX + 2);
+ .isEqualTo("test interface");
assertThat(this.bar).isEqualTo(BAZ + 2);
}
-
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedInheritedCfgAndTestInterfaceTestCase implements TestInterface {
-
- @Autowired
- @Qualifier("foo")
- String localFoo;
-
- @Autowired
- String bar;
-
- @Autowired
- ApplicationContext context;
-
-
- @Test
- void nestedTest() {
- assertThat(this.context).as("local ApplicationContext").isNotNull();
- assertThat(this.context.getParent()).as("parent ApplicationContext").isNotNull();
- assertThat(this.context.getParent().getParent()).as("grandparent ApplicationContext").isNotNull();
-
- assertThat(foo).as("foo")
- .isEqualTo(this.localFoo)
- .isEqualTo(this.context.getBean("foo", String.class))
- .isEqualTo("test interface");
- assertThat(this.bar).isEqualTo(BAZ + 2);
- }
- }
}
}
-
}
// -------------------------------------------------------------------------
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java
new file mode 100644
index 00000000000..8dafbb24832
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter.nested;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.NestedTestConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.TopLevelConfig;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
+
+/**
+ * Parameterized variant of {@link ConstructorInjectionTestClassScopedExtensionContextNestedTests}
+ * which tests {@link ParameterizedClass @ParameterizedClass} support.
+ *
+ * @author Sam Brannen
+ * @since 7.0
+ */
+@SpringJUnitConfig(TopLevelConfig.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
+@ParameterizedClass
+@ValueSource(strings = {"foo", "bar"})
+class ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests {
+
+ final String beanName;
+ final String foo;
+ final ApplicationContext context;
+
+
+ ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests(
+ String beanName, TestInfo testInfo, @Autowired String foo, ApplicationContext context) {
+
+ this.context = context;
+ this.beanName = beanName;
+ this.foo = foo;
+ }
+
+
+ @Test
+ void topLevelTest() {
+ assertThat(foo).isEqualTo("foo");
+ if (beanName.equals("foo")) {
+ assertThat(context.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ @Autowired
+ AutowiredConstructorTests(String bar, ApplicationContext context) {
+ this.bar = bar;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("foo");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorParameterTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ AutowiredConstructorParameterTests(@Autowired String bar, ApplicationContext context) {
+ this.bar = bar;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("foo");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class QualifiedConstructorParameterTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ QualifiedConstructorParameterTests(TestInfo testInfo, @Qualifier("bar") String s, ApplicationContext context) {
+ this.bar = s;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("foo");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class SpelConstructorParameterTests {
+
+ final String bar;
+ final int answer;
+ final ApplicationContext localContext;
+
+ SpelConstructorParameterTests(@Autowired String bar, TestInfo testInfo, @Value("#{ 6 * 7 }") int answer, ApplicationContext context) {
+ this.bar = bar;
+ this.answer = answer;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("foo");
+ assertThat(bar).isEqualTo("bar");
+ assertThat(answer).isEqualTo(42);
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+
+ @Configuration(proxyBeanMethods = false)
+ static class TopLevelConfig {
+
+ @Bean
+ String foo() {
+ return "foo";
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class NestedConfig {
+
+ @Bean
+ String bar() {
+ return "bar";
+ }
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
new file mode 100644
index 00000000000..69d9be4d8a6
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter.nested;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.NestedTestConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.TopLevelConfig;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
+
+/**
+ * Parameterized variant of {@link ConstructorInjectionTestMethodScopedExtensionContextNestedTests}
+ * which tests {@link ParameterizedClass @ParameterizedClass} support.
+ *
+ * @author Sam Brannen
+ * @since 7.0
+ */
+@SpringJUnitConfig(TopLevelConfig.class)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
+@ParameterizedClass
+@ValueSource(strings = {"foo", "bar"})
+class ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests {
+
+ final String beanName;
+ final String foo;
+ final ApplicationContext context;
+
+
+ ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests(
+ String beanName, TestInfo testInfo, @Autowired String foo, ApplicationContext context) {
+
+ this.context = context;
+ this.beanName = beanName;
+ this.foo = foo;
+ }
+
+
+ @Test
+ void topLevelTest() {
+ assertThat(foo).isEqualTo("foo");
+ if (beanName.equals("foo")) {
+ assertThat(context.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ @Autowired
+ AutowiredConstructorTests(String bar, ApplicationContext context) {
+ this.bar = bar;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class AutowiredConstructorParameterTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ AutowiredConstructorParameterTests(@Autowired String bar, ApplicationContext context) {
+ this.bar = bar;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class QualifiedConstructorParameterTests {
+
+ final String bar;
+ final ApplicationContext localContext;
+
+ QualifiedConstructorParameterTests(TestInfo testInfo, @Qualifier("bar") String s, ApplicationContext context) {
+ this.bar = s;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class SpelConstructorParameterTests {
+
+ final String bar;
+ final int answer;
+ final ApplicationContext localContext;
+
+ SpelConstructorParameterTests(@Autowired String bar, TestInfo testInfo, @Value("#{ 6 * 7 }") int answer, ApplicationContext context) {
+ this.bar = bar;
+ this.answer = answer;
+ this.localContext = context;
+ }
+
+ @Test
+ void nestedTest() {
+ assertThat(foo).isEqualTo("bar");
+ assertThat(bar).isEqualTo("bar");
+ assertThat(answer).isEqualTo(42);
+ if (beanName.equals("bar")) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+
+ @Configuration(proxyBeanMethods = false)
+ static class TopLevelConfig {
+
+ @Bean
+ String foo() {
+ return "foo";
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class NestedConfig {
+
+ @Bean
+ String bar() {
+ return "bar";
+ }
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java
new file mode 100644
index 00000000000..c160c3e05d4
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter.nested;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.NestedTestConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.TopLevelConfig;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
+
+/**
+ * Parameterized variant of {@link ContextConfigurationTestClassScopedExtensionContextNestedTests}
+ * which tests {@link ParameterizedClass @ParameterizedClass} support.
+ *
+ * @author Sam Brannen
+ * @since 7.0
+ */
+@SpringJUnitConfig(TopLevelConfig.class)
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
+@ParameterizedClass
+@ValueSource(strings = {"foo", "bar"})
+class ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests {
+
+ private static final String FOO = "foo";
+ private static final String BAR = "bar";
+ private static final String BAZ = "baz";
+
+ @Parameter
+ String beanName;
+
+ @Autowired
+ ApplicationContext context;
+
+ @Autowired
+ String foo;
+
+
+ @Test
+ void topLevelTest() {
+ assertThat(foo).isEqualTo(FOO);
+ if (beanName.equals(FOO)) {
+ assertThat(context.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class NestedTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ // In contrast to nested test classes running in JUnit 4, the foo
+ // field in the outer instance should have been injected from the
+ // test ApplicationContext for the outer instance.
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).as("foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class NestedWithInheritedConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ // Since the configuration is inherited, the foo field in the outer instance
+ // and the bar field in the inner instance should both have been injected
+ // from the test ApplicationContext for the outer instance.
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).isEqualTo(FOO);
+ assertThat(this.bar).isEqualTo(FOO);
+ if (beanName.equals(FOO)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @NestedTestConfiguration(OVERRIDE)
+ @SpringJUnitConfig(NestedConfig.class)
+ class DoubleNestedWithOverriddenConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ // In contrast to nested test classes running in JUnit 4, the foo
+ // field in the outer instance should have been injected from the
+ // test ApplicationContext for the outer instance.
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).as("foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ @ParameterizedClass
+ @ValueSource(ints = {1, 2})
+ class TripleNestedWithInheritedConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).as("foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+ @Autowired
+ String baz;
+
+
+ @Test
+ void test() {
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).as("foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ assertThat(this.baz).isEqualTo(BAZ);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+ }
+ }
+
+
+ @Configuration(proxyBeanMethods = false)
+ static class TopLevelConfig {
+
+ @Bean
+ String foo() {
+ return FOO;
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class NestedConfig {
+
+ @Bean
+ String bar() {
+ return BAR;
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class TestInterfaceConfig {
+
+ @Bean
+ String baz() {
+ return BAZ;
+ }
+ }
+
+ @ContextConfiguration(classes = TestInterfaceConfig.class)
+ interface TestInterface {
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java
new file mode 100644
index 00000000000..a3a3c294898
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2002-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter.nested;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.NestedTestConfiguration;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.nested.ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.TopLevelConfig;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
+import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
+
+/**
+ * Parameterized variant of {@link ContextConfigurationTestMethodScopedExtensionContextNestedTests}
+ * which tests {@link ParameterizedClass @ParameterizedClass} support.
+ *
+ * @author Sam Brannen
+ * @since 7.0
+ */
+@SpringJUnitConfig(TopLevelConfig.class)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
+@ParameterizedClass
+@ValueSource(strings = {"foo", "bar"})
+class ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests {
+
+ private static final String FOO = "foo";
+ private static final String BAR = "bar";
+ private static final String BAZ = "baz";
+
+ @Parameter
+ String beanName;
+
+ @Autowired
+ ApplicationContext context;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String foo;
+
+
+ @Test
+ void topLevelTest() {
+ assertThat(foo).isEqualTo(FOO);
+ if (beanName.equals(FOO)) {
+ assertThat(context.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @SpringJUnitConfig(NestedConfig.class)
+ class NestedTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class NestedTestsWithInheritedConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ // Since the configuration is inherited, the foo field in the outer instance
+ // and the bar field in the inner instance should both have been injected
+ // from the test ApplicationContext for the outer instance.
+ assertThat(foo).isEqualTo(FOO);
+ assertThat(this.localFoo).isEqualTo(FOO);
+ assertThat(this.bar).isEqualTo(FOO);
+ if (beanName.equals(FOO)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @NestedTestConfiguration(OVERRIDE)
+ @SpringJUnitConfig(NestedConfig.class)
+ class DoubleNestedWithOverriddenConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigTests {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ String bar;
+
+
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ if (beanName.equals(BAR)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
+
+ @Autowired
+ ApplicationContext localContext;
+
+ @Autowired(required = false)
+ @Qualifier("foo")
+ String localFoo;
+
+ @Autowired
+ @Qualifier("bar")
+ String bar;
+
+ @Autowired
+ String baz;
+
+
+ @Test
+ void test() {
+ assertThat(foo).as("foo bean should not be present").isNull();
+ assertThat(this.localFoo).as("local foo bean should not be present").isNull();
+ assertThat(this.bar).isEqualTo(BAR);
+ assertThat(this.baz).isEqualTo(BAZ);
+ if (beanName.equals(BAR) || beanName.equals(BAZ)) {
+ assertThat(localContext.getBean(beanName, String.class)).isEqualTo(beanName);
+ }
+ }
+ }
+ }
+ }
+
+
+ @Configuration(proxyBeanMethods = false)
+ static class TopLevelConfig {
+
+ @Bean
+ String foo() {
+ return FOO;
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class NestedConfig {
+
+ @Bean
+ String bar() {
+ return BAR;
+ }
+ }
+
+ @Configuration(proxyBeanMethods = false)
+ static class TestInterfaceConfig {
+
+ @Bean
+ String baz() {
+ return BAZ;
+ }
+ }
+
+ @ContextConfiguration(classes = TestInterfaceConfig.class)
+ interface TestInterface {
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java
index 6d2da9c7a4f..6f8a7f018c3 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java
@@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -44,6 +45,7 @@ import static org.springframework.test.context.TestConstructor.AutowireMode.ANNO
* @since 5.3
*/
@SpringJUnitConfig
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@TestConstructor(autowireMode = ALL)
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestConstructorTestClassScopedExtensionContextNestedTests {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestMethodScopedExtensionContextNestedTests.java
index 21d423155f2..cffd997dba8 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestMethodScopedExtensionContextNestedTests.java
@@ -19,7 +19,6 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -30,9 +29,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
import static org.springframework.test.context.TestConstructor.AutowireMode.ALL;
@@ -47,53 +43,52 @@ import static org.springframework.test.context.TestConstructor.AutowireMode.ANNO
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig
+@TestConstructor(autowireMode = ALL)
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestConstructorTestMethodScopedExtensionContextNestedTests {
+ TestConstructorTestMethodScopedExtensionContextNestedTests(String text) {
+ assertThat(text).isEqualTo("enigma");
+ }
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(8).succeeded(8).failed(0));
+ void test() {
}
+ @Nested
@SpringJUnitConfig(Config.class)
- @TestConstructor(autowireMode = ALL)
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- static class TestCase {
+ @TestConstructor(autowireMode = ANNOTATED)
+ class ConfigOverriddenByDefaultTests {
- TestCase(String text) {
+ @Autowired
+ ConfigOverriddenByDefaultTests(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
+ }
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class InheritedConfigTests {
- @Nested
- @SpringJUnitConfig(Config.class)
- @TestConstructor(autowireMode = ANNOTATED)
- class ConfigOverriddenByDefaultTestCase {
-
- @Autowired
- ConfigOverriddenByDefaultTestCase(String text) {
- assertThat(text).isEqualTo("enigma");
- }
+ InheritedConfigTests(String text) {
+ assertThat(text).isEqualTo("enigma");
+ }
- @Test
- void test() {
- }
+ @Test
+ void test() {
}
+
@Nested
- @NestedTestConfiguration(INHERIT)
- class InheritedConfigTestCase {
+ class DoubleNestedWithImplicitlyInheritedConfigTests {
- InheritedConfigTestCase(String text) {
+ DoubleNestedWithImplicitlyInheritedConfigTests(String text) {
assertThat(text).isEqualTo("enigma");
}
@@ -103,70 +98,57 @@ class TestConstructorTestMethodScopedExtensionContextNestedTests {
@Nested
- class DoubleNestedWithImplicitlyInheritedConfigTestCase {
+ class TripleNestedWithImplicitlyInheritedConfigTests {
- DoubleNestedWithImplicitlyInheritedConfigTestCase(String text) {
+ TripleNestedWithImplicitlyInheritedConfigTests(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
+ }
+ }
+ @Nested
+ @NestedTestConfiguration(OVERRIDE)
+ @SpringJUnitConfig(Config.class)
+ @TestConstructor(autowireMode = ANNOTATED)
+ class DoubleNestedWithOverriddenConfigTests {
- @Nested
- class TripleNestedWithImplicitlyInheritedConfigTestCase {
-
- TripleNestedWithImplicitlyInheritedConfigTestCase(String text) {
- assertThat(text).isEqualTo("enigma");
- }
+ DoubleNestedWithOverriddenConfigTests(@Autowired String text) {
+ assertThat(text).isEqualTo("enigma");
+ }
- @Test
- void test() {
- }
- }
+ @Test
+ void test() {
}
+
@Nested
- @NestedTestConfiguration(OVERRIDE)
- @SpringJUnitConfig(Config.class)
- @TestConstructor(autowireMode = ANNOTATED)
- class DoubleNestedWithOverriddenConfigTestCase {
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigTests {
- DoubleNestedWithOverriddenConfigTestCase(@Autowired String text) {
+ @Autowired
+ TripleNestedWithInheritedConfigTests(String text) {
assertThat(text).isEqualTo("enigma");
}
@Test
void test() {
}
+ }
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class TripleNestedWithInheritedConfigAndTestInterfaceTests implements TestInterface {
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedWithInheritedConfigTestCase {
-
- @Autowired
- TripleNestedWithInheritedConfigTestCase(String text) {
- assertThat(text).isEqualTo("enigma");
- }
-
- @Test
- void test() {
- }
+ TripleNestedWithInheritedConfigAndTestInterfaceTests(String text) {
+ assertThat(text).isEqualTo("enigma");
}
- @Nested
- @NestedTestConfiguration(INHERIT)
- class TripleNestedWithInheritedConfigAndTestInterfaceTestCase implements TestInterface {
-
- TripleNestedWithInheritedConfigAndTestInterfaceTestCase(String text) {
- assertThat(text).isEqualTo("enigma");
- }
-
- @Test
- void test() {
- }
+ @Test
+ void test() {
}
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java
index 6f1744da48f..5927cfa227b 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java
@@ -26,6 +26,7 @@ import org.springframework.core.env.Environment;
import org.springframework.test.context.NestedTestConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit.jupiter.SpringExtensionConfig;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,6 +43,7 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @since 5.3
*/
@SpringJUnitConfig
+@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
@TestPropertySource(properties = "p1 = v1")
@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestPropertySourceTestClassScopedExtensionContextNestedTests {
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestMethodScopedExtensionContextNestedTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestMethodScopedExtensionContextNestedTests.java
index 9be4d3db645..6a1e8ac1673 100644
--- a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestMethodScopedExtensionContextNestedTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestMethodScopedExtensionContextNestedTests.java
@@ -19,7 +19,6 @@ package org.springframework.test.context.junit.jupiter.nested;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.testkit.engine.EngineTestKit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@@ -30,9 +29,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME;
-import static org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope.TEST_METHOD;
-import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.INHERIT;
import static org.springframework.test.context.NestedTestConfiguration.EnclosingConfiguration.OVERRIDE;
@@ -45,139 +41,125 @@ import static org.springframework.test.context.NestedTestConfiguration.Enclosing
* @author Sam Brannen
* @since 6.2.13
*/
+@SpringJUnitConfig
+@TestPropertySource(properties = "p1 = v1")
+@NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
class TestPropertySourceTestMethodScopedExtensionContextNestedTests {
+ @Autowired
+ Environment env1;
+
+
@Test
- void runTests() {
- EngineTestKit.engine("junit-jupiter")
- .configurationParameter(DEFAULT_SCOPE_PROPERTY_NAME, TEST_METHOD.name())
- .selectors(selectClass(TestCase.class))
- .execute()
- .testEvents()
- .assertStatistics(stats -> stats.started(7).succeeded(7).failed(0));
+ void propertiesInEnvironment() {
+ assertThat(env1.getProperty("p1")).isEqualTo("v1");
}
- @SpringJUnitConfig(Config.class)
- @TestPropertySource(properties = "p1 = v1")
- @NestedTestConfiguration(OVERRIDE) // since INHERIT is now the global default
- static class TestCase {
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ class InheritedCfgTests {
@Autowired
- Environment env1;
+ Environment env2;
@Test
void propertiesInEnvironment() {
- assertThat(env1.getProperty("p1")).isEqualTo("v1");
+ assertThat(env1).isSameAs(env2);
+ assertThat(env2.getProperty("p1")).isEqualTo("v1");
}
+ }
+ @Nested
+ @SpringJUnitConfig(Config.class)
+ @TestPropertySource(properties = "p2 = v2")
+ class ConfigOverriddenByDefaultTests {
- @Nested
- @NestedTestConfiguration(INHERIT)
- class InheritedCfgTestCase {
-
- @Autowired
- Environment env2;
+ @Autowired
+ Environment env2;
- @Test
- void propertiesInEnvironment() {
- assertThat(env1).isSameAs(env2);
- assertThat(env2.getProperty("p1")).isEqualTo("v1");
- }
+ @Test
+ void propertiesInEnvironment() {
+ assertThat(env1).isSameAs(env2);
+ assertThat(env2.getProperty("p1")).isNull();
+ assertThat(env2.getProperty("p2")).isEqualTo("v2");
}
+ }
- @Nested
- @SpringJUnitConfig(Config.class)
- @TestPropertySource(properties = "p2 = v2")
- class ConfigOverriddenByDefaultTestCase {
+ @Nested
+ @NestedTestConfiguration(INHERIT)
+ @TestPropertySource(properties = "p2a = v2a")
+ @TestPropertySource(properties = "p2b = v2b")
+ class InheritedAndExtendedCfgTests {
- @Autowired
- Environment env2;
+ @Autowired
+ Environment env2;
- @Test
- void propertiesInEnvironment() {
- assertThat(env1).isSameAs(env2);
- assertThat(env2.getProperty("p1")).isNull();
- assertThat(env2.getProperty("p2")).isEqualTo("v2");
- }
+ @Test
+ void propertiesInEnvironment() {
+ assertThat(env1).isSameAs(env2);
+ assertThat(env2.getProperty("p1")).isEqualTo("v1");
+ assertThat(env2.getProperty("p2a")).isEqualTo("v2a");
+ assertThat(env2.getProperty("p2b")).isEqualTo("v2b");
}
+
@Nested
- @NestedTestConfiguration(INHERIT)
- @TestPropertySource(properties = "p2a = v2a")
- @TestPropertySource(properties = "p2b = v2b")
- class InheritedAndExtendedCfgTestCase {
+ @NestedTestConfiguration(OVERRIDE)
+ @SpringJUnitConfig(Config.class)
+ @TestPropertySource(properties = "p3 = v3")
+ class L3OverriddenCfgTests {
@Autowired
- Environment env2;
+ Environment env3;
@Test
void propertiesInEnvironment() {
- assertThat(env1).isSameAs(env2);
- assertThat(env2.getProperty("p1")).isEqualTo("v1");
- assertThat(env2.getProperty("p2a")).isEqualTo("v2a");
- assertThat(env2.getProperty("p2b")).isEqualTo("v2b");
+ assertThat(env1).isSameAs(env2).isSameAs(env3);
+ assertThat(env3.getProperty("p1")).isNull();
+ assertThat(env3.getProperty("p2")).isNull();
+ assertThat(env3.getProperty("p3")).isEqualTo("v3");
}
@Nested
- @NestedTestConfiguration(OVERRIDE)
- @SpringJUnitConfig(Config.class)
- @TestPropertySource(properties = "p3 = v3")
- class L3OverriddenCfgTestCase {
+ @NestedTestConfiguration(INHERIT)
+ @TestPropertySource(properties = {"p3 = v34", "p4 = v4"}, inheritProperties = false)
+ class L4InheritedCfgButOverriddenTestPropsTests {
@Autowired
- Environment env3;
+ Environment env4;
@Test
void propertiesInEnvironment() {
- assertThat(env1).isSameAs(env2).isSameAs(env3);
- assertThat(env3.getProperty("p1")).isNull();
- assertThat(env3.getProperty("p2")).isNull();
- assertThat(env3.getProperty("p3")).isEqualTo("v3");
+ assertThat(env1).isSameAs(env2).isSameAs(env3).isSameAs(env4);
+ assertThat(env4.getProperty("p1")).isNull();
+ assertThat(env4.getProperty("p2")).isNull();
+ assertThat(env4.getProperty("p3")).isEqualTo("v34");
+ assertThat(env4.getProperty("p4")).isEqualTo("v4");
}
-
@Nested
- @NestedTestConfiguration(INHERIT)
- @TestPropertySource(properties = {"p3 = v34", "p4 = v4"}, inheritProperties = false)
- class L4InheritedCfgButOverriddenTestPropertiesTestCase {
+ class L5InheritedCfgAndTestInterfaceTests implements TestInterface {
@Autowired
- Environment env4;
+ Environment env5;
@Test
void propertiesInEnvironment() {
- assertThat(env1).isSameAs(env2).isSameAs(env3).isSameAs(env4);
- assertThat(env4.getProperty("p1")).isNull();
- assertThat(env4.getProperty("p2")).isNull();
- assertThat(env4.getProperty("p3")).isEqualTo("v34");
- assertThat(env4.getProperty("p4")).isEqualTo("v4");
- }
-
- @Nested
- class L5InheritedCfgAndTestInterfaceTestCase implements TestInterface {
-
- @Autowired
- Environment env5;
-
-
- @Test
- void propertiesInEnvironment() {
- assertThat(env4).isSameAs(env5);
- assertThat(env5.getProperty("p1")).isNull();
- assertThat(env5.getProperty("p2")).isNull();
- assertThat(env5.getProperty("p3")).isEqualTo("v34");
- assertThat(env5.getProperty("p4")).isEqualTo("v4");
- assertThat(env5.getProperty("foo")).isEqualTo("bar");
- assertThat(env5.getProperty("enigma")).isEqualTo("42");
- }
+ assertThat(env4).isSameAs(env5);
+ assertThat(env5.getProperty("p1")).isNull();
+ assertThat(env5.getProperty("p2")).isNull();
+ assertThat(env5.getProperty("p3")).isEqualTo("v34");
+ assertThat(env5.getProperty("p4")).isEqualTo("v4");
+ assertThat(env5.getProperty("foo")).isEqualTo("bar");
+ assertThat(env5.getProperty("enigma")).isEqualTo("42");
}
}
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java b/spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java
index 9811a848d55..14eb4aa90ac 100644
--- a/spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java
@@ -21,10 +21,6 @@ import jakarta.persistence.PersistenceContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.TestInstantiationAwareExtension.ExtensionContextScope;
-import org.junit.platform.suite.api.ConfigurationParameter;
-import org.junit.platform.suite.api.SelectClasses;
-import org.junit.platform.suite.api.Suite;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.TestPropertySource;
@@ -37,62 +33,45 @@ import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
/**
- * Test {@link Suite @Suite} which selects a single test class and runs it with
- * {@link ExtensionContextScope#TEST_METHOD}.
+ * Transactional tests for JPA support with {@link Nested @Nested} test classes.
*
* @author Sam Brannen
* @since 6.2.13
* @see issue gh-34576
*/
-@Suite
-@SelectClasses(JpaPersonRepositoryTests.TestCase.class)
-@ConfigurationParameter(
- key = ExtensionContextScope.DEFAULT_SCOPE_PROPERTY_NAME,
- value = "test_method" // If this is changed to "default", NestedTests will fail.
-)
-// Even though this is a @Suite, it is intentionally named JpaPersonRepositoryTests
-// instead of JpaPersonRepositoryTestSuite, so that it is run with the Gradle build
-// due to the "*Tests" naming convention.
+@SpringJUnitConfig(JpaConfig.class)
+@Transactional
+@Sql(statements = "insert into person(id, name) values(0, 'Jane')")
class JpaPersonRepositoryTests {
- /**
- * Transactional tests for JPA support with {@link Nested @Nested} test classes.
- */
- @SpringJUnitConfig(JpaConfig.class)
- @Transactional
- @Sql(statements = "insert into person(id, name) values(0, 'Jane')")
- static class TestCase {
+ @PersistenceContext
+ EntityManager em;
- @PersistenceContext
- EntityManager em;
+ @Autowired
+ PersonRepository repo;
- @Autowired
- PersonRepository repo;
+ @BeforeEach
+ void setup() {
+ em.persist(new Person("John"));
+ em.flush();
+ }
- @BeforeEach
- void setup() {
- em.persist(new Person("John"));
- em.flush();
- }
+ @Test
+ void findAll() {
+ assertThat(repo.findAll()).map(Person::getName).containsExactlyInAnyOrder("Jane", "John");
+ }
+
+
+ @Nested
+ // Declare a random test property to ensure we get a different ApplicationContext.
+ @TestPropertySource(properties = "nested = true")
+ class NestedTests {
@Test
void findAll() {
assertThat(repo.findAll()).map(Person::getName).containsExactlyInAnyOrder("Jane", "John");
}
-
-
- @Nested
- // Declare a random test property to ensure we get a different ApplicationContext.
- @TestPropertySource(properties = "nested = true")
- class NestedTests {
-
- @Test
- void findAll() {
- assertThat(repo.findAll()).map(Person::getName).containsExactlyInAnyOrder("Jane", "John");
- }
- }
-
}
}