Honor spring.autoconfigure.exclude in test slices
Previously, the import selector for `@ImportAutoConfiguration` did not consider the spring.autoconfigure.exclude property when determining which auto-configurations to exclude. This meant that tests using a slice that included a particular auto-configuration would include it even if the application's configuration excluded it via spring.autoconfigure.exclude. Confusingly, this could result in a sliced test using an auto-configuration that would be excluded in a broader `@SpringBootTest`. This commit updates the ImportAutoConfigurationImportSelector to consider the spring.autoconfigure.exclude property so that sliced tests will use a subset of the auto-configurations that a `@SpringBootTest` would use. Fixes gh-21736
This commit is contained in:
@@ -233,13 +233,23 @@ public class AutoConfigurationImportSelector implements DeferredImportSelector,
|
||||
return excluded;
|
||||
}
|
||||
|
||||
private List<String> getExcludeAutoConfigurationsProperty() {
|
||||
if (getEnvironment() instanceof ConfigurableEnvironment) {
|
||||
Binder binder = Binder.get(getEnvironment());
|
||||
/**
|
||||
* Returns the auto-configurations excluded by the
|
||||
* {@code spring.autoconfigure.exclude} property.
|
||||
* @return excluded auto-configurations
|
||||
* @since 2.3.2
|
||||
*/
|
||||
protected List<String> getExcludeAutoConfigurationsProperty() {
|
||||
Environment environment = getEnvironment();
|
||||
if (environment == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (environment instanceof ConfigurableEnvironment) {
|
||||
Binder binder = Binder.get(environment);
|
||||
return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList)
|
||||
.orElse(Collections.emptyList());
|
||||
}
|
||||
String[] excludes = getEnvironment().getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);
|
||||
String[] excludes = environment.getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);
|
||||
return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -118,6 +118,7 @@ class ImportAutoConfigurationImportSelector extends AutoConfigurationImportSelec
|
||||
}
|
||||
}
|
||||
}
|
||||
exclusions.addAll(getExcludeAutoConfigurationsProperty());
|
||||
return exclusions;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,22 +25,19 @@ import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImportAutoConfigurationImportSelector}.
|
||||
@@ -54,12 +51,10 @@ class ImportAutoConfigurationImportSelectorTests {
|
||||
|
||||
private final ConfigurableListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
|
||||
@Mock
|
||||
private Environment environment;
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.importSelector.setBeanFactory(this.beanFactory);
|
||||
this.importSelector.setEnvironment(this.environment);
|
||||
this.importSelector.setResourceLoader(new DefaultResourceLoader());
|
||||
@@ -80,10 +75,11 @@ class ImportAutoConfigurationImportSelectorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void propertyExclusionsAreNotApplied() throws Exception {
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(ImportFreeMarker.class);
|
||||
this.importSelector.selectImports(annotationMetadata);
|
||||
verifyNoInteractions(this.environment);
|
||||
void propertyExclusionsAreApplied() throws IOException {
|
||||
this.environment.setProperty("spring.autoconfigure.exclude", FreeMarkerAutoConfiguration.class.getName());
|
||||
AnnotationMetadata annotationMetadata = getAnnotationMetadata(MultipleImports.class);
|
||||
String[] imports = this.importSelector.selectImports(annotationMetadata);
|
||||
assertThat(imports).containsExactly(ThymeleafAutoConfiguration.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -288,7 +284,9 @@ class ImportAutoConfigurationImportSelectorTests {
|
||||
@interface MetaImportAutoConfiguration {
|
||||
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class)
|
||||
Class<?>[] exclude() default {};
|
||||
Class<?>[] exclude() default {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -308,7 +306,9 @@ class ImportAutoConfigurationImportSelectorTests {
|
||||
@interface SelfAnnotating {
|
||||
|
||||
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
|
||||
Class<?>[] excludeAutoConfiguration() default {};
|
||||
Class<?>[] excludeAutoConfiguration() default {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user