Skip to content

Commit 6b437ec

Browse files
committed
Inherit enclosing class's configuration in nested tests
Fixes gh-12470
1 parent b0a1c2a commit 6b437ec

File tree

11 files changed

+171
-48
lines changed

11 files changed

+171
-48
lines changed

spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactory.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -21,12 +21,12 @@
2121
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2222
import org.springframework.boot.test.util.TestPropertyValues;
2323
import org.springframework.context.ConfigurableApplicationContext;
24-
import org.springframework.core.annotation.MergedAnnotations;
25-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
2624
import org.springframework.test.context.ContextConfigurationAttributes;
2725
import org.springframework.test.context.ContextCustomizer;
2826
import org.springframework.test.context.ContextCustomizerFactory;
2927
import org.springframework.test.context.MergedContextConfiguration;
28+
import org.springframework.test.context.TestContextAnnotationUtils;
29+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
3030

3131
/**
3232
* {@link ContextCustomizerFactory} to support
@@ -39,8 +39,9 @@ class OverrideAutoConfigurationContextCustomizerFactory implements ContextCustom
3939
@Override
4040
public ContextCustomizer createContextCustomizer(Class<?> testClass,
4141
List<ContextConfigurationAttributes> configurationAttributes) {
42-
boolean enabled = MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY)
43-
.get(OverrideAutoConfiguration.class).getValue("enabled", Boolean.class).orElse(true);
42+
AnnotationDescriptor<OverrideAutoConfiguration> descriptor = TestContextAnnotationUtils
43+
.findAnnotationDescriptor(testClass, OverrideAutoConfiguration.class);
44+
boolean enabled = (descriptor != null) ? descriptor.getAnnotation().enabled() : true;
4445
return !enabled ? new DisableAutoConfigurationContextCustomizer() : null;
4546
}
4647

spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/actuate/metrics/MetricsExportContextCustomizerFactory.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@
2020

2121
import org.springframework.boot.test.util.TestPropertyValues;
2222
import org.springframework.context.ConfigurableApplicationContext;
23-
import org.springframework.core.annotation.MergedAnnotations;
24-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
2523
import org.springframework.test.context.ContextConfigurationAttributes;
2624
import org.springframework.test.context.ContextCustomizer;
2725
import org.springframework.test.context.ContextCustomizerFactory;
2826
import org.springframework.test.context.MergedContextConfiguration;
27+
import org.springframework.test.context.TestContextAnnotationUtils;
2928

3029
/**
3130
* {@link ContextCustomizerFactory} that globally disables metrics export unless
@@ -38,8 +37,8 @@ class MetricsExportContextCustomizerFactory implements ContextCustomizerFactory
3837
@Override
3938
public ContextCustomizer createContextCustomizer(Class<?> testClass,
4039
List<ContextConfigurationAttributes> configAttributes) {
41-
boolean disableMetricsExport = !MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY)
42-
.get(AutoConfigureMetrics.class).isPresent();
40+
boolean disableMetricsExport = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
41+
AutoConfigureMetrics.class) == null;
4342
return disableMetricsExport ? new DisableMetricExportContextCustomizer() : null;
4443
}
4544

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/ImportsContextCustomizerFactory.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -22,10 +22,11 @@
2222
import org.springframework.context.annotation.Bean;
2323
import org.springframework.context.annotation.Import;
2424
import org.springframework.core.annotation.MergedAnnotations;
25-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
2625
import org.springframework.test.context.ContextConfigurationAttributes;
2726
import org.springframework.test.context.ContextCustomizer;
2827
import org.springframework.test.context.ContextCustomizerFactory;
28+
import org.springframework.test.context.TestContextAnnotationUtils;
29+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
2930
import org.springframework.util.Assert;
3031
import org.springframework.util.ReflectionUtils;
3132

@@ -41,9 +42,11 @@ class ImportsContextCustomizerFactory implements ContextCustomizerFactory {
4142
@Override
4243
public ContextCustomizer createContextCustomizer(Class<?> testClass,
4344
List<ContextConfigurationAttributes> configAttributes) {
44-
if (MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY).isPresent(Import.class)) {
45-
assertHasNoBeanMethods(testClass);
46-
return new ImportsContextCustomizer(testClass);
45+
AnnotationDescriptor<Import> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
46+
Import.class);
47+
if (descriptor != null) {
48+
assertHasNoBeanMethods(descriptor.getRootDeclaringClass());
49+
return new ImportsContextCustomizer(descriptor.getRootDeclaringClass());
4750
}
4851
return null;
4952
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import org.springframework.test.context.ContextLoader;
4747
import org.springframework.test.context.MergedContextConfiguration;
4848
import org.springframework.test.context.TestContext;
49+
import org.springframework.test.context.TestContextAnnotationUtils;
50+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
4951
import org.springframework.test.context.TestContextBootstrapper;
5052
import org.springframework.test.context.TestExecutionListener;
5153
import org.springframework.test.context.support.DefaultTestContextBootstrapper;
@@ -318,8 +320,12 @@ protected String[] getProperties(Class<?> testClass) {
318320
}
319321

320322
protected SpringBootTest getAnnotation(Class<?> testClass) {
321-
return MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS).get(SpringBootTest.class)
322-
.synthesize(MergedAnnotation::isPresent).orElse(null);
323+
AnnotationDescriptor<SpringBootTest> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
324+
SpringBootTest.class);
325+
if (descriptor != null) {
326+
return descriptor.getAnnotation();
327+
}
328+
return null;
323329
}
324330

325331
protected void verifyConfiguration(Class<?> testClass) {

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestWebEnvironment.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818

1919
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
2020
import org.springframework.context.ConfigurableApplicationContext;
21-
import org.springframework.core.annotation.MergedAnnotations;
2221
import org.springframework.test.context.ContextCustomizer;
2322
import org.springframework.test.context.MergedContextConfiguration;
23+
import org.springframework.test.context.TestContextAnnotationUtils;
24+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
2425

2526
/**
2627
* {@link ContextCustomizer} to track the web environment that is used in a
@@ -35,8 +36,9 @@ class SpringBootTestWebEnvironment implements ContextCustomizer {
3536
private final WebEnvironment webEnvironment;
3637

3738
SpringBootTestWebEnvironment(Class<?> testClass) {
38-
this.webEnvironment = MergedAnnotations.from(testClass, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)
39-
.get(SpringBootTest.class).getValue("webEnvironment", WebEnvironment.class).orElse(null);
39+
AnnotationDescriptor<SpringBootTest> descriptor = TestContextAnnotationUtils.findAnnotationDescriptor(testClass,
40+
SpringBootTest.class);
41+
this.webEnvironment = (descriptor != null) ? descriptor.getAnnotation().webEnvironment() : null;
4042
}
4143

4244
@Override

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/mock/mockito/MockitoContextCustomizerFactory.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -21,6 +21,7 @@
2121
import org.springframework.test.context.ContextConfigurationAttributes;
2222
import org.springframework.test.context.ContextCustomizer;
2323
import org.springframework.test.context.ContextCustomizerFactory;
24+
import org.springframework.test.context.TestContextAnnotationUtils;
2425

2526
/**
2627
* A {@link ContextCustomizerFactory} to add Mockito support.
@@ -35,8 +36,15 @@ public ContextCustomizer createContextCustomizer(Class<?> testClass,
3536
// We gather the explicit mock definitions here since they form part of the
3637
// MergedContextConfiguration key. Different mocks need to have a different key.
3738
DefinitionsParser parser = new DefinitionsParser();
38-
parser.parse(testClass);
39+
parseDefinitions(testClass, parser);
3940
return new MockitoContextCustomizer(parser.getDefinitions());
4041
}
4142

43+
private void parseDefinitions(Class<?> testClass, DefinitionsParser parser) {
44+
parser.parse(testClass);
45+
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
46+
parseDefinitions(testClass.getEnclosingClass(), parser);
47+
}
48+
}
49+
4250
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizer.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -29,7 +29,6 @@
2929
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
3030
import org.springframework.beans.factory.support.RootBeanDefinition;
3131
import org.springframework.boot.test.context.SpringBootTest;
32-
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
3332
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
3433
import org.springframework.boot.web.client.RestTemplateBuilder;
3534
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
@@ -38,11 +37,10 @@
3837
import org.springframework.context.ConfigurableApplicationContext;
3938
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
4039
import org.springframework.core.Ordered;
41-
import org.springframework.core.annotation.MergedAnnotation;
42-
import org.springframework.core.annotation.MergedAnnotations;
43-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
4440
import org.springframework.test.context.ContextCustomizer;
4541
import org.springframework.test.context.MergedContextConfiguration;
42+
import org.springframework.test.context.TestContextAnnotationUtils;
43+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
4644

4745
/**
4846
* {@link ContextCustomizer} for {@link TestRestTemplate}.
@@ -55,10 +53,9 @@ class TestRestTemplateContextCustomizer implements ContextCustomizer {
5553
@Override
5654
public void customizeContext(ConfigurableApplicationContext context,
5755
MergedContextConfiguration mergedContextConfiguration) {
58-
MergedAnnotation<?> annotation = MergedAnnotations
59-
.from(mergedContextConfiguration.getTestClass(), SearchStrategy.INHERITED_ANNOTATIONS)
60-
.get(SpringBootTest.class);
61-
if (annotation.getEnum("webEnvironment", WebEnvironment.class).isEmbedded()) {
56+
AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
57+
.findAnnotationDescriptor(mergedContextConfiguration.getTestClass(), SpringBootTest.class);
58+
if (springBootTest.getAnnotation().webEnvironment().isEmbedded()) {
6259
registerTestRestTemplate(context);
6360
}
6461
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplateContextCustomizerFactory.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -19,11 +19,11 @@
1919
import java.util.List;
2020

2121
import org.springframework.boot.test.context.SpringBootTest;
22-
import org.springframework.core.annotation.MergedAnnotations;
23-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
2422
import org.springframework.test.context.ContextConfigurationAttributes;
2523
import org.springframework.test.context.ContextCustomizer;
2624
import org.springframework.test.context.ContextCustomizerFactory;
25+
import org.springframework.test.context.TestContextAnnotationUtils;
26+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
2727

2828
/**
2929
* {@link ContextCustomizerFactory} for {@link TestRestTemplate}.
@@ -36,8 +36,9 @@ class TestRestTemplateContextCustomizerFactory implements ContextCustomizerFacto
3636
@Override
3737
public ContextCustomizer createContextCustomizer(Class<?> testClass,
3838
List<ContextConfigurationAttributes> configAttributes) {
39-
MergedAnnotations annotations = MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS);
40-
if (annotations.isPresent(SpringBootTest.class)) {
39+
AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
40+
.findAnnotationDescriptor(testClass, SpringBootTest.class);
41+
if (springBootTest != null) {
4142
return new TestRestTemplateContextCustomizer();
4243
}
4344
return null;

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizer.java

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -31,19 +31,17 @@
3131
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
3232
import org.springframework.beans.factory.support.RootBeanDefinition;
3333
import org.springframework.boot.test.context.SpringBootTest;
34-
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
3534
import org.springframework.boot.web.codec.CodecCustomizer;
3635
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
3736
import org.springframework.context.ApplicationContext;
3837
import org.springframework.context.ApplicationContextAware;
3938
import org.springframework.context.ConfigurableApplicationContext;
4039
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
4140
import org.springframework.core.Ordered;
42-
import org.springframework.core.annotation.MergedAnnotation;
43-
import org.springframework.core.annotation.MergedAnnotations;
44-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
4541
import org.springframework.test.context.ContextCustomizer;
4642
import org.springframework.test.context.MergedContextConfiguration;
43+
import org.springframework.test.context.TestContextAnnotationUtils;
44+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
4745
import org.springframework.test.web.reactive.server.WebTestClient;
4846
import org.springframework.util.CollectionUtils;
4947
import org.springframework.web.reactive.function.client.ExchangeStrategies;
@@ -57,9 +55,9 @@ class WebTestClientContextCustomizer implements ContextCustomizer {
5755

5856
@Override
5957
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
60-
MergedAnnotation<?> annotation = MergedAnnotations
61-
.from(mergedConfig.getTestClass(), SearchStrategy.INHERITED_ANNOTATIONS).get(SpringBootTest.class);
62-
if (annotation.getEnum("webEnvironment", WebEnvironment.class).isEmbedded()) {
58+
AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
59+
.findAnnotationDescriptor(mergedConfig.getTestClass(), SpringBootTest.class);
60+
if (springBootTest.getAnnotation().webEnvironment().isEmbedded()) {
6361
registerWebTestClient(context);
6462
}
6563
}

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/reactive/server/WebTestClientContextCustomizerFactory.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 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.
@@ -19,11 +19,11 @@
1919
import java.util.List;
2020

2121
import org.springframework.boot.test.context.SpringBootTest;
22-
import org.springframework.core.annotation.MergedAnnotations;
23-
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
2422
import org.springframework.test.context.ContextConfigurationAttributes;
2523
import org.springframework.test.context.ContextCustomizer;
2624
import org.springframework.test.context.ContextCustomizerFactory;
25+
import org.springframework.test.context.TestContextAnnotationUtils;
26+
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
2727
import org.springframework.util.ClassUtils;
2828

2929
/**
@@ -38,8 +38,9 @@ class WebTestClientContextCustomizerFactory implements ContextCustomizerFactory
3838
@Override
3939
public ContextCustomizer createContextCustomizer(Class<?> testClass,
4040
List<ContextConfigurationAttributes> configAttributes) {
41-
MergedAnnotations annotations = MergedAnnotations.from(testClass, SearchStrategy.INHERITED_ANNOTATIONS);
42-
if (isWebClientPresent() && annotations.isPresent(SpringBootTest.class)) {
41+
AnnotationDescriptor<SpringBootTest> springBootTest = TestContextAnnotationUtils
42+
.findAnnotationDescriptor(testClass, SpringBootTest.class);
43+
if (springBootTest != null) {
4344
return new WebTestClientContextCustomizer();
4445
}
4546
return null;

0 commit comments

Comments
 (0)