mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 20:19:06 +00:00
Merge branch '3.5.x' into 4.0.x
Closes gh-50012
This commit is contained in:
+34
-18
@@ -18,9 +18,11 @@ package org.springframework.boot.test.context;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -53,6 +55,7 @@ import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.test.context.ContextCustomizer;
|
||||
import org.springframework.test.context.MergedContextConfiguration;
|
||||
import org.springframework.test.context.TestContextAnnotationUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
@@ -66,17 +69,30 @@ import org.springframework.util.ReflectionUtils;
|
||||
*/
|
||||
class ImportsContextCustomizer implements ContextCustomizer {
|
||||
|
||||
private static final String TEST_CLASS_NAME_ATTRIBUTE = "testClassName";
|
||||
private static final String TEST_CLASS_NAMES_ATTRIBUTE = "testClassNames";
|
||||
|
||||
private final String testClassName;
|
||||
private final String[] testClassNames;
|
||||
|
||||
private final ContextCustomizerKey key;
|
||||
|
||||
ImportsContextCustomizer(Class<?> testClass) {
|
||||
this.testClassName = testClass.getName();
|
||||
this.testClassNames = collectClassNames(testClass);
|
||||
this.key = new ContextCustomizerKey(testClass);
|
||||
}
|
||||
|
||||
private static String[] collectClassNames(Class<?> source) {
|
||||
List<String> classNames = new ArrayList<>();
|
||||
collectClassNames(source, classNames);
|
||||
return classNames.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private static void collectClassNames(Class<?> source, List<String> classNames) {
|
||||
classNames.add(source.getName());
|
||||
if (TestContextAnnotationUtils.searchEnclosingClass(source)) {
|
||||
collectClassNames(source.getEnclosingClass(), classNames);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customizeContext(ConfigurableApplicationContext context,
|
||||
MergedContextConfiguration mergedContextConfiguration) {
|
||||
@@ -90,13 +106,13 @@ class ImportsContextCustomizer implements ContextCustomizer {
|
||||
BeanDefinition definition = registerBean(registry, reader, ImportsCleanupPostProcessor.BEAN_NAME,
|
||||
ImportsCleanupPostProcessor.class);
|
||||
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
definition.getConstructorArgumentValues().addIndexedArgumentValue(0, this.testClassName);
|
||||
definition.getConstructorArgumentValues().addIndexedArgumentValue(0, this.testClassNames);
|
||||
}
|
||||
|
||||
private void registerImportsConfiguration(BeanDefinitionRegistry registry, AnnotatedBeanDefinitionReader reader) {
|
||||
BeanDefinition definition = registerBean(registry, reader, ImportsConfiguration.BEAN_NAME,
|
||||
ImportsConfiguration.class);
|
||||
definition.setAttribute(TEST_CLASS_NAME_ATTRIBUTE, this.testClassName);
|
||||
definition.setAttribute(TEST_CLASS_NAMES_ATTRIBUTE, this.testClassNames);
|
||||
}
|
||||
|
||||
private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {
|
||||
@@ -169,8 +185,8 @@ class ImportsContextCustomizer implements ContextCustomizer {
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
BeanDefinition definition = this.beanFactory.getBeanDefinition(ImportsConfiguration.BEAN_NAME);
|
||||
Object testClassName = definition.getAttribute(TEST_CLASS_NAME_ATTRIBUTE);
|
||||
return (testClassName != null) ? new String[] { (String) testClassName } : NO_IMPORTS;
|
||||
Object testClassNames = definition.getAttribute(TEST_CLASS_NAMES_ATTRIBUTE);
|
||||
return (testClassNames != null) ? (String[]) testClassNames : NO_IMPORTS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -184,10 +200,10 @@ class ImportsContextCustomizer implements ContextCustomizer {
|
||||
|
||||
static final String BEAN_NAME = ImportsCleanupPostProcessor.class.getName();
|
||||
|
||||
private final String testClassName;
|
||||
private final String[] testClassNames;
|
||||
|
||||
ImportsCleanupPostProcessor(String testClassName) {
|
||||
this.testClassName = testClassName;
|
||||
ImportsCleanupPostProcessor(String[] testClassNames) {
|
||||
this.testClassNames = testClassNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,15 +212,15 @@ class ImportsContextCustomizer implements ContextCustomizer {
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
||||
for (String testClassName : this.testClassNames) {
|
||||
removeBean(testClassName, registry);
|
||||
}
|
||||
removeBean(ImportsConfiguration.BEAN_NAME, registry);
|
||||
}
|
||||
|
||||
private void removeBean(String beanName, BeanDefinitionRegistry registry) {
|
||||
try {
|
||||
String[] names = registry.getBeanDefinitionNames();
|
||||
for (String name : names) {
|
||||
BeanDefinition definition = registry.getBeanDefinition(name);
|
||||
if (this.testClassName.equals(definition.getBeanClassName())) {
|
||||
registry.removeBeanDefinition(name);
|
||||
}
|
||||
}
|
||||
registry.removeBeanDefinition(ImportsConfiguration.BEAN_NAME);
|
||||
registry.removeBeanDefinition(beanName);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
// Ignore
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.test.context;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTestImportTests.ImportedByContainingTests;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootTest @SpringBootTest} with {@link Import @Import}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@TestPropertySource(properties = "a=alpha")
|
||||
@Import(ImportedByContainingTests.class)
|
||||
class SpringBootTestImportTests {
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(classes = Config.class)
|
||||
@Import(ImportedByNestedTests.class)
|
||||
class NestedTests {
|
||||
|
||||
@Autowired(required = false)
|
||||
private ImportedByContainingTests importedByContainingTests;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ImportedByNestedTests importedByNestedTests;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Test
|
||||
void sameClassImportIsHonored() {
|
||||
assertThat(this.importedByNestedTests).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containingClassImportIsHonored() {
|
||||
assertThat(this.importedByContainingTests).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void containingClassTestPropertySourceIsHonored() {
|
||||
assertThat(this.environment.getProperty("a")).isEqualTo("alpha");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
static class ImportedByNestedTests {
|
||||
|
||||
}
|
||||
|
||||
static class ImportedByContainingTests {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user