Skip to content

Commit f2ac025

Browse files
committed
Merge from sbrannen/SPR-12051
* SPR-12051: Introduce @TestPropertySource support in the TCF
2 parents 6665634 + 2cf4147 commit f2ac025

File tree

30 files changed

+1686
-126
lines changed

30 files changed

+1686
-126
lines changed

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,19 @@
5353
* The term <em>annotated class</em> can refer to any of the following.
5454
*
5555
* <ul>
56-
* <li>A class annotated with @{@link org.springframework.context.annotation.Configuration
57-
* Configuration}</li>
56+
* <li>A class annotated with {@link org.springframework.context.annotation.Configuration @Configuration}</li>
5857
* <li>A component (i.e., a class annotated with
5958
* {@link org.springframework.stereotype.Component @Component},
6059
* {@link org.springframework.stereotype.Service @Service},
6160
* {@link org.springframework.stereotype.Repository @Repository}, etc.)</li>
6261
* <li>A JSR-330 compliant class that is annotated with {@code javax.inject} annotations</li>
63-
* <li>Any other class that contains {@link org.springframework.context.annotation.Bean
64-
* @Bean}-methods</li>
62+
* <li>Any other class that contains {@link org.springframework.context.annotation.Bean @Bean}-methods</li>
6563
* </ul>
6664
*
6765
* <p>
68-
* Consult the Javadoc for {@link org.springframework.context.annotation.Configuration
69-
* @Configuration} and {@link org.springframework.context.annotation.Bean @Bean} for
70-
* further information regarding the configuration and semantics of
71-
* <em>annotated classes</em>.
66+
* Consult the Javadoc for {@link org.springframework.context.annotation.Configuration @Configuration}
67+
* and {@link org.springframework.context.annotation.Bean @Bean} for further
68+
* information regarding the configuration and semantics of <em>annotated classes</em>.
7269
*
7370
* <p>
7471
* As of Spring Framework 4.0, this annotation may be used as a <em>meta-annotation</em>
@@ -78,6 +75,7 @@
7875
* @since 2.5
7976
* @see ContextHierarchy
8077
* @see ActiveProfiles
78+
* @see TestPropertySource
8179
* @see ContextLoader
8280
* @see SmartContextLoader
8381
* @see ContextConfigurationAttributes

spring-test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java

Lines changed: 116 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 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.
@@ -34,15 +34,17 @@
3434
/**
3535
* {@code MergedContextConfiguration} encapsulates the <em>merged</em>
3636
* context configuration declared on a test class and all of its superclasses
37-
* via {@link ContextConfiguration @ContextConfiguration} and
38-
* {@link ActiveProfiles @ActiveProfiles}.
37+
* via {@link ContextConfiguration @ContextConfiguration},
38+
* {@link ActiveProfiles @ActiveProfiles}, and
39+
* {@link TestPropertySource @TestPropertySource}.
3940
*
40-
* <p>Merged resource locations, annotated classes, and active profiles
41-
* represent all declared values in the test class hierarchy taking into
42-
* consideration the semantics of the
43-
* {@link ContextConfiguration#inheritLocations inheritLocations} and
44-
* {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in
45-
* {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively.
41+
* <p>Merged context resource locations, annotated classes, active profiles,
42+
* property resource locations, and in-lined properties represent all declared
43+
* values in the test class hierarchy taking into consideration the semantics
44+
* of the {@link ContextConfiguration#inheritLocations},
45+
* {@link ActiveProfiles#inheritProfiles},
46+
* {@link TestPropertySource#inheritLocations}, and
47+
* {@link TestPropertySource#inheritProperties} flags.
4648
*
4749
* <p>A {@link SmartContextLoader} uses {@code MergedContextConfiguration}
4850
* to load an {@link org.springframework.context.ApplicationContext ApplicationContext}.
@@ -73,13 +75,15 @@ public class MergedContextConfiguration implements Serializable {
7375
private final Class<?>[] classes;
7476
private final Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses;
7577
private final String[] activeProfiles;
78+
private final String[] propertySourceLocations;
79+
private final String[] propertySourceProperties;
7680
private final ContextLoader contextLoader;
7781
private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate;
7882
private final MergedContextConfiguration parent;
7983

8084

81-
private static String[] processLocations(String[] locations) {
82-
return locations == null ? EMPTY_STRING_ARRAY : locations;
85+
private static String[] processStrings(String[] array) {
86+
return array == null ? EMPTY_STRING_ARRAY : array;
8387
}
8488

8589
private static Class<?>[] processClasses(Class<?>[] classes) {
@@ -115,20 +119,15 @@ protected static String nullSafeToString(ContextLoader contextLoader) {
115119

116120
/**
117121
* Create a new {@code MergedContextConfiguration} instance for the
118-
* supplied test class, resource locations, annotated classes, active
119-
* profiles, and {@code ContextLoader}.
120-
*
121-
* <p>If a {@code null} value is supplied for {@code locations},
122-
* {@code classes}, or {@code activeProfiles} an empty array will
123-
* be stored instead. Furthermore, active profiles will be sorted, and duplicate
124-
* profiles will be removed.
122+
* supplied parameters.
123+
* <p>Delegates to
124+
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
125125
*
126126
* @param testClass the test class for which the configuration was merged
127-
* @param locations the merged resource locations
127+
* @param locations the merged context resource locations
128128
* @param classes the merged annotated classes
129129
* @param activeProfiles the merged active bean definition profiles
130130
* @param contextLoader the resolved {@code ContextLoader}
131-
* @see #MergedContextConfiguration(Class, String[], Class[], Set, String[], ContextLoader)
132131
*/
133132
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
134133
String[] activeProfiles, ContextLoader contextLoader) {
@@ -137,18 +136,12 @@ public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<
137136

138137
/**
139138
* Create a new {@code MergedContextConfiguration} instance for the
140-
* supplied test class, resource locations, annotated classes, context
141-
* initializers, active profiles, and {@code ContextLoader}.
142-
*
143-
* <p>If a {@code null} value is supplied for {@code locations},
144-
* {@code classes}, or {@code activeProfiles} an empty array will
145-
* be stored instead. If a {@code null} value is supplied for the
146-
* {@code contextInitializerClasses} an empty set will be stored instead.
147-
* Furthermore, active profiles will be sorted, and duplicate profiles will
148-
* be removed.
139+
* supplied parameters.
140+
* <p>Delegates to
141+
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
149142
*
150143
* @param testClass the test class for which the configuration was merged
151-
* @param locations the merged resource locations
144+
* @param locations the merged context resource locations
152145
* @param classes the merged annotated classes
153146
* @param contextInitializerClasses the merged context initializer classes
154147
* @param activeProfiles the merged active bean definition profiles
@@ -166,19 +159,12 @@ public MergedContextConfiguration(
166159

167160
/**
168161
* Create a new {@code MergedContextConfiguration} instance for the
169-
* supplied test class, resource locations, annotated classes, context
170-
* initializers, active profiles, {@code ContextLoader}, and parent
171-
* configuration.
172-
*
173-
* <p>If a {@code null} value is supplied for {@code locations},
174-
* {@code classes}, or {@code activeProfiles} an empty array will
175-
* be stored instead. If a {@code null} value is supplied for the
176-
* {@code contextInitializerClasses} an empty set will be stored instead.
177-
* Furthermore, active profiles will be sorted, and duplicate profiles will
178-
* be removed.
162+
* supplied parameters.
163+
* <p>Delegates to
164+
* {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
179165
*
180166
* @param testClass the test class for which the configuration was merged
181-
* @param locations the merged resource locations
167+
* @param locations the merged context resource locations
182168
* @param classes the merged annotated classes
183169
* @param contextInitializerClasses the merged context initializer classes
184170
* @param activeProfiles the merged active bean definition profiles
@@ -195,11 +181,50 @@ public MergedContextConfiguration(
195181
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
196182
String[] activeProfiles, ContextLoader contextLoader,
197183
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, MergedContextConfiguration parent) {
184+
this(testClass, locations, classes, contextInitializerClasses, activeProfiles, null, null, contextLoader,
185+
cacheAwareContextLoaderDelegate, parent);
186+
}
187+
188+
/**
189+
* Create a new {@code MergedContextConfiguration} instance for the
190+
* supplied parameters.
191+
*
192+
* <p>If a {@code null} value is supplied for {@code locations},
193+
* {@code classes}, {@code activeProfiles}, {@code propertySourceLocations},
194+
* or {@code propertySourceProperties} an empty array will be stored instead.
195+
* If a {@code null} value is supplied for the
196+
* {@code contextInitializerClasses} an empty set will be stored instead.
197+
* Furthermore, active profiles will be sorted, and duplicate profiles
198+
* will be removed.
199+
*
200+
* @param testClass the test class for which the configuration was merged
201+
* @param locations the merged context resource locations
202+
* @param classes the merged annotated classes
203+
* @param contextInitializerClasses the merged context initializer classes
204+
* @param activeProfiles the merged active bean definition profiles
205+
* @param propertySourceLocations the merged {@code PropertySource} locations
206+
* @param propertySourceProperties the merged {@code PropertySource} properties
207+
* @param contextLoader the resolved {@code ContextLoader}
208+
* @param cacheAwareContextLoaderDelegate a cache-aware context loader
209+
* delegate with which to retrieve the parent context
210+
* @param parent the parent configuration or {@code null} if there is no parent
211+
* @since 4.1
212+
*/
213+
public MergedContextConfiguration(
214+
Class<?> testClass,
215+
String[] locations,
216+
Class<?>[] classes,
217+
Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>> contextInitializerClasses,
218+
String[] activeProfiles, String[] propertySourceLocations, String[] propertySourceProperties,
219+
ContextLoader contextLoader, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate,
220+
MergedContextConfiguration parent) {
198221
this.testClass = testClass;
199-
this.locations = processLocations(locations);
222+
this.locations = processStrings(locations);
200223
this.classes = processClasses(classes);
201224
this.contextInitializerClasses = processContextInitializerClasses(contextInitializerClasses);
202225
this.activeProfiles = processActiveProfiles(activeProfiles);
226+
this.propertySourceLocations = processStrings(propertySourceLocations);
227+
this.propertySourceProperties = processStrings(propertySourceProperties);
203228
this.contextLoader = contextLoader;
204229
this.cacheAwareContextLoaderDelegate = cacheAwareContextLoaderDelegate;
205230
this.parent = parent;
@@ -213,7 +238,10 @@ public Class<?> getTestClass() {
213238
}
214239

215240
/**
216-
* Get the merged resource locations for the {@linkplain #getTestClass() test class}.
241+
* Get the merged resource locations for {@code ApplicationContext}
242+
* configuration files for the {@linkplain #getTestClass() test class}.
243+
* <p>Context resource locations typically represent XML configuration
244+
* files or Groovy scripts.
217245
*/
218246
public String[] getLocations() {
219247
return locations;
@@ -228,7 +256,7 @@ public Class<?>[] getClasses() {
228256

229257
/**
230258
* Determine if this {@code MergedContextConfiguration} instance has
231-
* path-based resource locations.
259+
* path-based context resource locations.
232260
*
233261
* @return {@code true} if the {@link #getLocations() locations} array is not empty
234262
* @since 4.0.4
@@ -254,7 +282,7 @@ public boolean hasClasses() {
254282

255283
/**
256284
* Determine if this {@code MergedContextConfiguration} instance has
257-
* either path-based resource locations or class-based resources.
285+
* either path-based context resource locations or class-based resources.
258286
*
259287
* @return {@code true} if either the {@link #getLocations() locations}
260288
* or the {@link #getClasses() classes} array is not empty
@@ -275,12 +303,36 @@ public Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableA
275303
}
276304

277305
/**
278-
* Get the merged active bean definition profiles for the {@linkplain #getTestClass() test class}.
306+
* Get the merged active bean definition profiles for the
307+
* {@linkplain #getTestClass() test class}.
308+
* @see ActiveProfiles
279309
*/
280310
public String[] getActiveProfiles() {
281311
return activeProfiles;
282312
}
283313

314+
/**
315+
* Get the merged resource locations for test {@code PropertySources} for the
316+
* {@linkplain #getTestClass() test class}.
317+
* @see TestPropertySource#locations
318+
* @see java.util.Properties
319+
*/
320+
public String[] getPropertySourceLocations() {
321+
return propertySourceLocations;
322+
}
323+
324+
/**
325+
* Get the merged test {@code PropertySource} properties for the
326+
* {@linkplain #getTestClass() test class}.
327+
* <p>Properties will be loaded into the {@code Environment}'s set of
328+
* {@code PropertySources}.
329+
* @see TestPropertySource#properties
330+
* @see java.util.Properties
331+
*/
332+
public String[] getPropertySourceProperties() {
333+
return propertySourceProperties;
334+
}
335+
284336
/**
285337
* Get the resolved {@link ContextLoader} for the {@linkplain #getTestClass() test class}.
286338
*/
@@ -334,6 +386,8 @@ public int hashCode() {
334386
result = prime * result + Arrays.hashCode(classes);
335387
result = prime * result + contextInitializerClasses.hashCode();
336388
result = prime * result + Arrays.hashCode(activeProfiles);
389+
result = prime * result + Arrays.hashCode(propertySourceLocations);
390+
result = prime * result + Arrays.hashCode(propertySourceProperties);
337391
result = prime * result + (parent == null ? 0 : parent.hashCode());
338392
result = prime * result + nullSafeToString(contextLoader).hashCode();
339393
return result;
@@ -345,6 +399,8 @@ public int hashCode() {
345399
* {@linkplain #getClasses() annotated classes},
346400
* {@linkplain #getContextInitializerClasses() context initializer classes},
347401
* {@linkplain #getActiveProfiles() active profiles},
402+
* {@linkplain #getPropertySourceLocations() property source locations},
403+
* {@linkplain #getPropertySourceProperties() property source properties},
348404
* {@linkplain #getParent() parents}, and the fully qualified names of their
349405
* {@link #getContextLoader() ContextLoaders}.
350406
*/
@@ -376,6 +432,14 @@ public boolean equals(Object obj) {
376432
return false;
377433
}
378434

435+
if (!Arrays.equals(this.propertySourceLocations, that.propertySourceLocations)) {
436+
return false;
437+
}
438+
439+
if (!Arrays.equals(this.propertySourceProperties, that.propertySourceProperties)) {
440+
return false;
441+
}
442+
379443
if (this.parent == null) {
380444
if (that.parent != null) {
381445
return false;
@@ -396,8 +460,10 @@ else if (!this.parent.equals(that.parent)) {
396460
* Provide a String representation of the {@linkplain #getTestClass() test class},
397461
* {@linkplain #getLocations() locations}, {@linkplain #getClasses() annotated classes},
398462
* {@linkplain #getContextInitializerClasses() context initializer classes},
399-
* {@linkplain #getActiveProfiles() active profiles}, the name of the
400-
* {@link #getContextLoader() ContextLoader}, and the
463+
* {@linkplain #getActiveProfiles() active profiles},
464+
* {@linkplain #getPropertySourceLocations() property source locations},
465+
* {@linkplain #getPropertySourceProperties() property source properties},
466+
* the name of the {@link #getContextLoader() ContextLoader}, and the
401467
* {@linkplain #getParent() parent configuration}.
402468
*/
403469
@Override
@@ -408,6 +474,8 @@ public String toString() {
408474
.append("classes", ObjectUtils.nullSafeToString(classes))//
409475
.append("contextInitializerClasses", ObjectUtils.nullSafeToString(contextInitializerClasses))//
410476
.append("activeProfiles", ObjectUtils.nullSafeToString(activeProfiles))//
477+
.append("propertySourceLocations", ObjectUtils.nullSafeToString(propertySourceLocations))//
478+
.append("propertySourceProperties", ObjectUtils.nullSafeToString(propertySourceProperties))//
411479
.append("contextLoader", nullSafeToString(contextLoader))//
412480
.append("parent", parent)//
413481
.toString();

0 commit comments

Comments
 (0)