Skip to content

Commit 85ffbbc

Browse files
committed
Make core auto-configuration tests more independent
Closes gh-44513
1 parent 5683d39 commit 85ffbbc

6 files changed

+93
-56
lines changed

Diff for: spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigurationImportSelectorTests.java

+38-24
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@
2929
import org.springframework.beans.factory.BeanFactoryAware;
3030
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
3131
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
32-
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
33-
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
34-
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
3532
import org.springframework.boot.context.annotation.ImportCandidates;
33+
import org.springframework.boot.testsupport.classpath.resources.WithResource;
3634
import org.springframework.context.annotation.Configuration;
3735
import org.springframework.core.io.DefaultResourceLoader;
3836
import org.springframework.core.type.AnnotationMetadata;
@@ -48,6 +46,15 @@
4846
* @author Stephane Nicoll
4947
* @author Madhura Bhave
5048
*/
49+
@WithResource(name = "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports", content = """
50+
com.example.one.FirstAutoConfiguration
51+
com.example.two.SecondAutoConfiguration
52+
com.example.three.ThirdAutoConfiguration
53+
com.example.four.FourthAutoConfiguration
54+
com.example.five.FifthAutoConfiguration
55+
com.example.six.SixthAutoConfiguration
56+
org.springframework.boot.autoconfigure.AutoConfigurationImportSelectorTests$SeventhAutoConfiguration
57+
""")
5158
class AutoConfigurationImportSelectorTests {
5259

5360
private final TestAutoConfigurationImportSelector importSelector = new TestAutoConfigurationImportSelector();
@@ -63,6 +70,7 @@ void setup() {
6370
this.importSelector.setBeanFactory(this.beanFactory);
6471
this.importSelector.setEnvironment(this.environment);
6572
this.importSelector.setResourceLoader(new DefaultResourceLoader());
73+
this.importSelector.setBeanClassLoader(Thread.currentThread().getContextClassLoader());
6674
}
6775

6876
@Test
@@ -77,78 +85,78 @@ void classExclusionsAreApplied() {
7785
String[] imports = selectImports(EnableAutoConfigurationWithClassExclusions.class);
7886
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
7987
assertThat(this.importSelector.getLastEvent().getExclusions())
80-
.contains(FreeMarkerAutoConfiguration.class.getName());
88+
.contains(SeventhAutoConfiguration.class.getName());
8189
}
8290

8391
@Test
8492
void classExclusionsAreAppliedWhenUsingSpringBootApplication() {
8593
String[] imports = selectImports(SpringBootApplicationWithClassExclusions.class);
8694
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
8795
assertThat(this.importSelector.getLastEvent().getExclusions())
88-
.contains(FreeMarkerAutoConfiguration.class.getName());
96+
.contains(SeventhAutoConfiguration.class.getName());
8997
}
9098

9199
@Test
92100
void classNamesExclusionsAreApplied() {
93101
String[] imports = selectImports(EnableAutoConfigurationWithClassNameExclusions.class);
94102
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
95103
assertThat(this.importSelector.getLastEvent().getExclusions())
96-
.contains(MustacheAutoConfiguration.class.getName());
104+
.contains("com.example.one.FirstAutoConfiguration");
97105
}
98106

99107
@Test
100108
void classNamesExclusionsAreAppliedWhenUsingSpringBootApplication() {
101109
String[] imports = selectImports(SpringBootApplicationWithClassNameExclusions.class);
102110
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
103111
assertThat(this.importSelector.getLastEvent().getExclusions())
104-
.contains(MustacheAutoConfiguration.class.getName());
112+
.contains("com.example.three.ThirdAutoConfiguration");
105113
}
106114

107115
@Test
108116
void propertyExclusionsAreApplied() {
109-
this.environment.setProperty("spring.autoconfigure.exclude", FreeMarkerAutoConfiguration.class.getName());
117+
this.environment.setProperty("spring.autoconfigure.exclude", "com.example.three.ThirdAutoConfiguration");
110118
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
111119
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 1);
112120
assertThat(this.importSelector.getLastEvent().getExclusions())
113-
.contains(FreeMarkerAutoConfiguration.class.getName());
121+
.contains("com.example.three.ThirdAutoConfiguration");
114122
}
115123

116124
@Test
117125
void severalPropertyExclusionsAreApplied() {
118126
this.environment.setProperty("spring.autoconfigure.exclude",
119-
FreeMarkerAutoConfiguration.class.getName() + "," + MustacheAutoConfiguration.class.getName());
127+
"com.example.two.SecondAutoConfiguration,com.example.four.FourthAutoConfiguration");
120128
testSeveralPropertyExclusionsAreApplied();
121129
}
122130

123131
@Test
124132
void severalPropertyExclusionsAreAppliedWithExtraSpaces() {
125133
this.environment.setProperty("spring.autoconfigure.exclude",
126-
FreeMarkerAutoConfiguration.class.getName() + " , " + MustacheAutoConfiguration.class.getName() + " ");
134+
"com.example.two.SecondAutoConfiguration , com.example.four.FourthAutoConfiguration ");
127135
testSeveralPropertyExclusionsAreApplied();
128136
}
129137

130138
@Test
131139
void severalPropertyYamlExclusionsAreApplied() {
132-
this.environment.setProperty("spring.autoconfigure.exclude[0]", FreeMarkerAutoConfiguration.class.getName());
133-
this.environment.setProperty("spring.autoconfigure.exclude[1]", MustacheAutoConfiguration.class.getName());
140+
this.environment.setProperty("spring.autoconfigure.exclude[0]", "com.example.two.SecondAutoConfiguration");
141+
this.environment.setProperty("spring.autoconfigure.exclude[1]", "com.example.four.FourthAutoConfiguration");
134142
testSeveralPropertyExclusionsAreApplied();
135143
}
136144

137145
private void testSeveralPropertyExclusionsAreApplied() {
138146
String[] imports = selectImports(BasicEnableAutoConfiguration.class);
139147
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 2);
140148
assertThat(this.importSelector.getLastEvent().getExclusions())
141-
.contains(FreeMarkerAutoConfiguration.class.getName(), MustacheAutoConfiguration.class.getName());
149+
.contains("com.example.two.SecondAutoConfiguration", "com.example.four.FourthAutoConfiguration");
142150
}
143151

144152
@Test
145153
void combinedExclusionsAreApplied() {
146-
this.environment.setProperty("spring.autoconfigure.exclude", ThymeleafAutoConfiguration.class.getName());
154+
this.environment.setProperty("spring.autoconfigure.exclude", "com.example.one.FirstAutoConfiguration");
147155
String[] imports = selectImports(EnableAutoConfigurationWithClassAndClassNameExclusions.class);
148156
assertThat(imports).hasSize(getAutoConfigurationClassNames().size() - 3);
149157
assertThat(this.importSelector.getLastEvent().getExclusions()).contains(
150-
FreeMarkerAutoConfiguration.class.getName(), MustacheAutoConfiguration.class.getName(),
151-
ThymeleafAutoConfiguration.class.getName());
158+
"com.example.one.FirstAutoConfiguration", "com.example.five.FifthAutoConfiguration",
159+
SeventhAutoConfiguration.class.getName());
152160
}
153161

154162
@Test
@@ -213,7 +221,8 @@ private String[] selectImports(Class<?> source) {
213221
}
214222

215223
private List<String> getAutoConfigurationClassNames() {
216-
return ImportCandidates.load(AutoConfiguration.class, getClass().getClassLoader()).getCandidates();
224+
return ImportCandidates.load(AutoConfiguration.class, Thread.currentThread().getContextClassLoader())
225+
.getCandidates();
217226
}
218227

219228
private final class TestAutoConfigurationImportSelector extends AutoConfigurationImportSelector {
@@ -278,23 +287,23 @@ private final class BasicEnableAutoConfiguration {
278287

279288
}
280289

281-
@EnableAutoConfiguration(exclude = FreeMarkerAutoConfiguration.class)
290+
@EnableAutoConfiguration(exclude = SeventhAutoConfiguration.class)
282291
private final class EnableAutoConfigurationWithClassExclusions {
283292

284293
}
285294

286-
@SpringBootApplication(exclude = FreeMarkerAutoConfiguration.class)
295+
@SpringBootApplication(exclude = SeventhAutoConfiguration.class)
287296
private final class SpringBootApplicationWithClassExclusions {
288297

289298
}
290299

291-
@EnableAutoConfiguration(excludeName = "org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration")
300+
@EnableAutoConfiguration(excludeName = "com.example.one.FirstAutoConfiguration")
292301
private final class EnableAutoConfigurationWithClassNameExclusions {
293302

294303
}
295304

296-
@EnableAutoConfiguration(exclude = MustacheAutoConfiguration.class,
297-
excludeName = "org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration")
305+
@EnableAutoConfiguration(exclude = SeventhAutoConfiguration.class,
306+
excludeName = "com.example.five.FifthAutoConfiguration")
298307
private final class EnableAutoConfigurationWithClassAndClassNameExclusions {
299308

300309
}
@@ -315,9 +324,14 @@ private final class EnableAutoConfigurationWithAbsentClassNameExclude {
315324

316325
}
317326

318-
@SpringBootApplication(excludeName = "org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration")
327+
@SpringBootApplication(excludeName = "com.example.three.ThirdAutoConfiguration")
319328
private final class SpringBootApplicationWithClassNameExclusions {
320329

321330
}
322331

332+
@AutoConfiguration
333+
static class SeventhAutoConfiguration {
334+
335+
}
336+
323337
}

Diff for: spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ImportAutoConfigurationImportSelectorTests.java

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,7 +79,7 @@ void importsAreSelectedFromImportsFile() throws Exception {
7979
AnnotationMetadata annotationMetadata = getAnnotationMetadata(FromImportsFile.class);
8080
String[] imports = this.importSelector.selectImports(annotationMetadata);
8181
assertThat(imports).containsExactly(
82-
"org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration",
82+
"org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration",
8383
"org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration");
8484
}
8585

@@ -89,8 +89,8 @@ void importsSelectedFromImportsFileIgnoreMissingOptionalClasses() throws Excepti
8989
FromImportsFileIgnoresMissingOptionalClasses.class);
9090
String[] imports = this.importSelector.selectImports(annotationMetadata);
9191
assertThat(imports).containsExactly(
92-
"org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration",
93-
"org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration");
92+
"org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration",
93+
"org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$AnotherImportedAutoConfiguration");
9494
}
9595

9696
@Test
@@ -356,4 +356,14 @@ protected Collection<String> loadFactoryNames(Class<?> source) {
356356

357357
}
358358

359+
@AutoConfiguration
360+
static class ImportedAutoConfiguration {
361+
362+
}
363+
364+
@AutoConfiguration
365+
static class AnotherImportedAutoConfiguration {
366+
367+
}
368+
359369
}

Diff for: spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionEvaluationReportTests.java

+6-25
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.condition;
1818

19-
import java.util.ArrayList;
2019
import java.util.Iterator;
21-
import java.util.List;
2220
import java.util.Map;
2321

2422
import org.junit.jupiter.api.BeforeEach;
@@ -31,6 +29,7 @@
3129
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
3230
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcome;
3331
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport.ConditionAndOutcomes;
32+
import org.springframework.boot.autoconfigure.condition.config.UniqueShortNameAutoConfiguration;
3433
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage;
3534
import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration;
3635
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
@@ -184,24 +183,6 @@ void testDuplicateConditionAndOutcomes() {
184183
assertThat(outcomes).hasSize(2);
185184
}
186185

187-
@Test
188-
void duplicateOutcomes() {
189-
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DuplicateConfig.class);
190-
ConditionEvaluationReport report = ConditionEvaluationReport.get(context.getBeanFactory());
191-
String autoconfigKey = MultipartAutoConfiguration.class.getName();
192-
ConditionAndOutcomes outcomes = report.getConditionAndOutcomesBySource().get(autoconfigKey);
193-
assertThat(outcomes).isNotNull();
194-
assertThat(outcomes).hasSize(2);
195-
List<String> messages = new ArrayList<>();
196-
for (ConditionAndOutcome outcome : outcomes) {
197-
messages.add(outcome.getOutcome().getMessage());
198-
}
199-
assertThat(messages).anyMatch((message) -> message.contains("@ConditionalOnClass found required classes "
200-
+ "'jakarta.servlet.Servlet', 'org.springframework.web.multipart."
201-
+ "support.StandardServletMultipartResolver', 'jakarta.servlet.MultipartConfigElement'"));
202-
context.close();
203-
}
204-
205186
@Test
206187
void negativeOuterPositiveInnerBean() {
207188
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
@@ -220,13 +201,13 @@ void negativeOuterPositiveInnerBean() {
220201
@Test
221202
void reportWhenSameShortNamePresentMoreThanOnceShouldUseFullyQualifiedName() {
222203
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
223-
context.register(WebMvcAutoConfiguration.class,
204+
context.register(UniqueShortNameAutoConfiguration.class,
224205
org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration.class,
225206
org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration.class);
226207
context.refresh();
227208
ConditionEvaluationReport report = ConditionEvaluationReport.get(context.getBeanFactory());
228209
assertThat(report.getConditionAndOutcomesBySource()).containsKeys(
229-
"org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration",
210+
"org.springframework.boot.autoconfigure.condition.config.UniqueShortNameAutoConfiguration",
230211
"org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration",
231212
"org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration");
232213
context.close();
@@ -235,17 +216,17 @@ void reportWhenSameShortNamePresentMoreThanOnceShouldUseFullyQualifiedName() {
235216
@Test
236217
void reportMessageWhenSameShortNamePresentMoreThanOnceShouldUseFullyQualifiedName() {
237218
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
238-
context.register(WebMvcAutoConfiguration.class,
219+
context.register(UniqueShortNameAutoConfiguration.class,
239220
org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration.class,
240221
org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration.class);
241222
context.refresh();
242223
ConditionEvaluationReport report = ConditionEvaluationReport.get(context.getBeanFactory());
243224
String reportMessage = new ConditionEvaluationReportMessage(report).toString();
244-
assertThat(reportMessage).contains("WebMvcAutoConfiguration",
225+
assertThat(reportMessage).contains("UniqueShortNameAutoConfiguration",
245226
"org.springframework.boot.autoconfigure.condition.config.first.SampleAutoConfiguration",
246227
"org.springframework.boot.autoconfigure.condition.config.second.SampleAutoConfiguration");
247228
assertThat(reportMessage)
248-
.doesNotContain("org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration");
229+
.doesNotContain("org.springframework.boot.autoconfigure.condition.config.UniqueShortNameAutoConfiguration");
249230
context.close();
250231
}
251232

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.condition.config;
18+
19+
import org.springframework.boot.autoconfigure.AutoConfiguration;
20+
import org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport;
21+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
22+
23+
/**
24+
* Uniquely named auto-configuration for {@link ConditionEvaluationReport} tests.
25+
*
26+
* @author Andy Wilkinson
27+
*/
28+
@AutoConfiguration
29+
@ConditionalOnProperty("unique")
30+
public class UniqueShortNameAutoConfiguration {
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
1+
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
22
org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
optional:org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration
1+
optional:org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$ImportedAutoConfiguration
22
optional:org.springframework.boot.autoconfigure.missing.MissingAutoConfiguration
3-
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
3+
org.springframework.boot.autoconfigure.ImportAutoConfigurationImportSelectorTests$AnotherImportedAutoConfiguration

0 commit comments

Comments
 (0)