Browse Source

Use test-method scoped ExtensionContext in the SpringExtension

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
pull/35718/head
Sam Brannen 5 months ago
parent
commit
41ae13df5d
  1. 2
      spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java
  2. 3
      spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java
  3. 1
      spring-test/src/main/java/org/springframework/test/context/TestConstructor.java
  4. 1
      spring-test/src/main/java/org/springframework/test/context/TestContext.java
  5. 1
      spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java
  6. 116
      spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java
  7. 68
      spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java
  8. 9
      spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java
  9. 11
      spring-test/src/main/java/org/springframework/test/context/junit/jupiter/web/SpringJUnitWebConfig.java
  10. 2
      spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
  11. 143
      spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
  12. 2
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
  13. 132
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
  14. 5
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java
  15. 77
      spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java
  16. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java
  17. 143
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java
  18. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java
  19. 136
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
  20. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java
  21. 149
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestMethodScopedExtensionContextNestedTests.java
  22. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java
  23. 146
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java
  24. 186
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java
  25. 184
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java
  26. 257
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java
  27. 249
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java
  28. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java
  29. 122
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestMethodScopedExtensionContextNestedTests.java
  30. 2
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java
  31. 156
      spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestMethodScopedExtensionContextNestedTests.java
  32. 67
      spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java

2
spring-test/src/main/java/org/springframework/test/context/ContextConfiguration.java

@ -80,6 +80,8 @@ import org.springframework.core.annotation.AliasFor; @@ -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

3
spring-test/src/main/java/org/springframework/test/context/NestedTestConfiguration.java

@ -95,6 +95,9 @@ import org.jspecify.annotations.Nullable; @@ -95,6 +95,9 @@ import org.jspecify.annotations.Nullable;
* <li>{@link TestConstructor @TestConstructor}</li>
* </ul>
*
* <p>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

1
spring-test/src/main/java/org/springframework/test/context/TestConstructor.java

@ -61,6 +61,7 @@ import org.jspecify.annotations.Nullable; @@ -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

1
spring-test/src/main/java/org/springframework/test/context/TestContext.java

@ -117,6 +117,7 @@ public interface TestContext extends AttributeAccessor, Serializable { @@ -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();

1
spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java

@ -169,6 +169,7 @@ public interface TestExecutionListener { @@ -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 {
}

116
spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtension.java

@ -48,6 +48,7 @@ import org.junit.platform.commons.annotation.Testable; @@ -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; @@ -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; @@ -66,18 +69,37 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
* {@code SpringExtension} integrates the <em>Spring TestContext Framework</em>
* into the JUnit Jupiter testing framework.
*
* <p>To use this extension, simply annotate a JUnit Jupiter based test class with
* {@code @ExtendWith(SpringExtension.class)}, {@code @SpringJUnitConfig}, or
* {@code @SpringJUnitWebConfig}.
* <p>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.
*
* <p>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 &mdash; or if a developer wishes to
* switch to test-class scoped semantics &mdash; 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()
* &#64;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 @@ -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<Class<?>, 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<Class<? extends Annotation>> JUPITER_ANNOTATION_TYPES =
@ -119,6 +149,19 @@ public class SpringExtension implements BeforeAllCallback, AfterAllCallback, Tes @@ -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}.
* <p>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 @@ -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 @@ -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 @@ -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.
* <p>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<SpringExtensionConfig> 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;
}
}

68
spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringExtensionConfig.java

@ -0,0 +1,68 @@ @@ -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}.
*
* <p>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.
*
* <p>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.
*
* <p>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();
}

9
spring-test/src/main/java/org/springframework/test/context/junit/jupiter/SpringJUnitConfig.java

@ -42,10 +42,11 @@ import org.springframework.test.context.ContextLoader; @@ -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

11
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; @@ -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

2
spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java

@ -26,6 +26,7 @@ import org.springframework.context.ConfigurableApplicationContext; @@ -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; @@ -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")

143
spring-test/src/test/java/org/springframework/test/context/bean/override/convention/TestBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java

@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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");
}
}
}

2
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java

@ -30,6 +30,7 @@ import org.springframework.context.annotation.Configuration; @@ -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; @@ -44,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 6.2
*/
@SpringJUnitConfig
@SpringExtensionConfig(useTestClassScopedExtensionContext = true)
public class MockitoBeanByNameLookupTestClassScopedExtensionContextIntegrationTests {
@MockitoBean("field")

132
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java

@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName; @@ -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; @@ -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 @@ -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 @@ -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 @@ -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);
}
}

5
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestClassScopedExtensionContextIntegrationTests.java

@ -30,7 +30,7 @@ import org.springframework.context.annotation.Configuration; @@ -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; @@ -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")

77
spring-test/src/test/java/org/springframework/test/context/bean/override/mockito/MockitoSpyBeanByNameLookupTestMethodScopedExtensionContextIntegrationTests.java

@ -20,7 +20,6 @@ import org.junit.jupiter.api.DisplayName; @@ -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; @@ -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 @@ -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 {

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestClassScopedExtensionContextNestedTests.java

@ -30,6 +30,7 @@ import org.springframework.test.context.ActiveProfiles; @@ -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 @@ -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 {

143
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ActiveProfilesTestMethodScopedExtensionContextNestedTests.java

@ -21,7 +21,6 @@ import java.util.List; @@ -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; @@ -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 @@ -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<String> 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<String> strings;
List<String> 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<String> localStrings;
@Autowired
List<String> 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<String> localStrings;
@Autowired
List<String> 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<String> localStrings;
@ -124,15 +126,14 @@ class ActiveProfilesTestMethodScopedExtensionContextNestedTests { @@ -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<String> localStrings;
@ -142,41 +143,23 @@ class ActiveProfilesTestMethodScopedExtensionContextNestedTests { @@ -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<String> 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<String> localStrings;
@Autowired
List<String> 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");
}
}
}

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestClassScopedExtensionContextNestedTests.java

@ -28,6 +28,7 @@ import org.springframework.context.annotation.Bean; @@ -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 @@ -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 {

136
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ConstructorInjectionTestMethodScopedExtensionContextNestedTests.java

@ -20,7 +20,6 @@ import org.junit.jupiter.api.Nested; @@ -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; @@ -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 @@ -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);
}
}
// -------------------------------------------------------------------------

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextConfigurationTestClassScopedExtensionContextNestedTests.java

@ -27,6 +27,7 @@ import org.springframework.context.annotation.Configuration; @@ -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 @@ -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 {

149
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; @@ -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; @@ -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 @@ -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 { @@ -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 { @@ -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);
}
}
}
}
// -------------------------------------------------------------------------

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestClassScopedExtensionContextNestedTests.java

@ -31,6 +31,7 @@ import org.springframework.test.context.ContextHierarchy; @@ -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 @@ -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")

146
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ContextHierarchyTestMethodScopedExtensionContextNestedTests.java

@ -20,7 +20,6 @@ import org.junit.jupiter.api.Nested; @@ -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; @@ -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 @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}
}
}
}
// -------------------------------------------------------------------------

186
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestClassScopedExtensionContextNestedTests.java

@ -0,0 +1,186 @@ @@ -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";
}
}
}

184
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedConstructorInjectionTestMethodScopedExtensionContextNestedTests.java

@ -0,0 +1,184 @@ @@ -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";
}
}
}

257
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestClassScopedExtensionContextNestedTests.java

@ -0,0 +1,257 @@ @@ -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 {
}
}

249
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/ParameterizedCtxConfigTestMethodScopedExtensionContextNestedTests.java

@ -0,0 +1,249 @@ @@ -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 {
}
}

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestConstructorTestClassScopedExtensionContextNestedTests.java

@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration; @@ -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 @@ -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 {

122
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; @@ -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; @@ -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 @@ -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 { @@ -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() {
}
}
}

2
spring-test/src/test/java/org/springframework/test/context/junit/jupiter/nested/TestPropertySourceTestClassScopedExtensionContextNestedTests.java

@ -26,6 +26,7 @@ import org.springframework.core.env.Environment; @@ -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 @@ -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 {

156
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; @@ -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; @@ -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 @@ -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");
}
}
}

67
spring-test/src/test/java/org/springframework/test/context/orm/jpa/JpaPersonRepositoryTests.java

@ -21,10 +21,6 @@ import jakarta.persistence.PersistenceContext; @@ -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; @@ -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 <a href="https://github.com/spring-projects/spring-framework/issues/34576">issue gh-34576</a>
*/
@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");
}
}
}
}

Loading…
Cancel
Save