001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.context; 018 019import java.lang.annotation.Documented; 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Inherited; 022import java.lang.annotation.Repeatable; 023import java.lang.annotation.Retention; 024import java.lang.annotation.RetentionPolicy; 025import java.lang.annotation.Target; 026 027import org.springframework.core.annotation.AliasFor; 028 029/** 030 * {@code @TestPropertySource} is a class-level annotation that is used to 031 * configure the {@link #locations} of properties files and inlined 032 * {@link #properties} to be added to the {@code Environment}'s set of 033 * {@code PropertySources} for an 034 * {@link org.springframework.context.ApplicationContext ApplicationContext} 035 * for integration tests. 036 * 037 * <h3>Precedence</h3> 038 * <p>Test property sources have higher precedence than those loaded from the 039 * operating system's environment or Java system properties as well as property 040 * sources added by the application declaratively via 041 * {@link org.springframework.context.annotation.PropertySource @PropertySource} 042 * or programmatically (e.g., via an 043 * {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer} 044 * or some other means). Thus, test property sources can be used to selectively 045 * override properties defined in system and application property sources. 046 * Furthermore, inlined {@link #properties} have higher precedence than 047 * properties loaded from resource {@link #locations}. Note, however, that 048 * properties registered via {@link DynamicPropertySource @DynamicPropertySource} 049 * have higher precedence than those loaded via {@code @TestPropertySource}. 050 * 051 * <h3>Default Properties File Detection</h3> 052 * <p>If {@code @TestPropertySource} is declared as an <em>empty</em> annotation 053 * (i.e., without explicit values for {@link #locations} or {@link #properties}), 054 * an attempt will be made to detect a <em>default</em> properties file relative 055 * to the class that declared the annotation. For example, if the annotated test 056 * class is {@code com.example.MyTest}, the corresponding default properties file 057 * is {@code "classpath:com/example/MyTest.properties"}. If the default cannot be 058 * detected, an {@link IllegalStateException} will be thrown. 059 * 060 * <h3>Enabling @TestPropertySource</h3> 061 * <p>{@code @TestPropertySource} is enabled if the configured 062 * {@linkplain ContextConfiguration#loader context loader} honors it. Every 063 * {@code SmartContextLoader} that is a subclass of either 064 * {@link org.springframework.test.context.support.AbstractGenericContextLoader AbstractGenericContextLoader} or 065 * {@link org.springframework.test.context.web.AbstractGenericWebContextLoader AbstractGenericWebContextLoader} 066 * provides automatic support for {@code @TestPropertySource}, and this includes 067 * every {@code SmartContextLoader} provided by the Spring TestContext Framework. 068 * 069 * <h3>Miscellaneous</h3> 070 * <ul> 071 * <li>Typically, {@code @TestPropertySource} will be used in conjunction with 072 * {@link ContextConfiguration @ContextConfiguration}.</li> 073 * <li>As of Spring Framework 5.2, {@code @TestPropertySource} can be used as a 074 * <em>{@linkplain Repeatable repeatable}</em> annotation.</li> 075 * <li>This annotation may be used as a <em>meta-annotation</em> to create 076 * custom <em>composed annotations</em>; however, caution should be taken if 077 * this annotation and {@code @ContextConfiguration} are combined on a composed 078 * annotation since the {@code locations} and {@code inheritLocations} attributes 079 * of both annotations can lead to ambiguity during the attribute resolution 080 * process.</li> 081 * </ul> 082 * 083 * @author Sam Brannen 084 * @since 4.1 085 * @see ContextConfiguration 086 * @see DynamicPropertySource 087 * @see org.springframework.core.env.Environment 088 * @see org.springframework.core.env.PropertySource 089 * @see org.springframework.context.annotation.PropertySource 090 */ 091@Target(ElementType.TYPE) 092@Retention(RetentionPolicy.RUNTIME) 093@Documented 094@Inherited 095@Repeatable(TestPropertySources.class) 096public @interface TestPropertySource { 097 098 /** 099 * Alias for {@link #locations}. 100 * <p>This attribute may <strong>not</strong> be used in conjunction with 101 * {@link #locations}, but it may be used <em>instead</em> of {@link #locations}. 102 * @see #locations 103 */ 104 @AliasFor("locations") 105 String[] value() default {}; 106 107 /** 108 * The resource locations of properties files to be loaded into the 109 * {@code Environment}'s set of {@code PropertySources}. Each location 110 * will be added to the enclosing {@code Environment} as its own property 111 * source, in the order declared. 112 * <h3>Supported File Formats</h3> 113 * <p>Both traditional and XML-based properties file formats are supported 114 * — for example, {@code "classpath:/com/example/test.properties"} 115 * or {@code "file:/path/to/file.xml"}. 116 * <h3>Path Resource Semantics</h3> 117 * <p>Each path will be interpreted as a Spring 118 * {@link org.springframework.core.io.Resource Resource}. A plain path 119 * — for example, {@code "test.properties"} — will be treated as a 120 * classpath resource that is <em>relative</em> to the package in which the 121 * test class is defined. A path starting with a slash will be treated as an 122 * <em>absolute</em> classpath resource, for example: 123 * {@code "/org/example/test.xml"}. A path which references a 124 * URL (e.g., a path prefixed with 125 * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX classpath:}, 126 * {@link org.springframework.util.ResourceUtils#FILE_URL_PREFIX file:}, 127 * {@code http:}, etc.) will be loaded using the specified resource protocol. 128 * Resource location wildcards (e.g. <code>**/*.properties</code>) 129 * are not permitted: each location must evaluate to exactly one 130 * {@code .properties} or {@code .xml} resource. Property placeholders 131 * in paths (i.e., <code>${...}</code>) will be 132 * {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) resolved} 133 * against the {@code Environment}. 134 * <h3>Default Properties File Detection</h3> 135 * <p>See the class-level Javadoc for a discussion on detection of defaults. 136 * <h3>Precedence</h3> 137 * <p>Properties loaded from resource locations have lower precedence than 138 * inlined {@link #properties}. 139 * <p>This attribute may <strong>not</strong> be used in conjunction with 140 * {@link #value}, but it may be used <em>instead</em> of {@link #value}. 141 * @see #inheritLocations 142 * @see #value 143 * @see #properties 144 * @see org.springframework.core.env.PropertySource 145 */ 146 @AliasFor("value") 147 String[] locations() default {}; 148 149 /** 150 * Whether or not test property source {@link #locations} from superclasses 151 * should be <em>inherited</em>. 152 * <p>The default value is {@code true}, which means that a test class will 153 * <em>inherit</em> property source locations defined by a superclass. 154 * Specifically, the property source locations for a test class will be 155 * appended to the list of property source locations defined by a superclass. 156 * Thus, subclasses have the option of <em>extending</em> the list of test 157 * property source locations. 158 * <p>If {@code inheritLocations} is set to {@code false}, the property 159 * source locations for the test class will <em>shadow</em> and effectively 160 * replace any property source locations defined by a superclass. 161 * <p>In the following example, the {@code ApplicationContext} for 162 * {@code BaseTest} will be loaded using only the {@code "base.properties"} 163 * file as a test property source. In contrast, the {@code ApplicationContext} 164 * for {@code ExtendedTest} will be loaded using the {@code "base.properties"} 165 * <strong>and</strong> {@code "extended.properties"} files as test property 166 * source locations. 167 * <pre class="code"> 168 * @TestPropertySource("base.properties") 169 * @ContextConfiguration 170 * public class BaseTest { 171 * // ... 172 * } 173 * 174 * @TestPropertySource("extended.properties") 175 * @ContextConfiguration 176 * public class ExtendedTest extends BaseTest { 177 * // ... 178 * }</pre> 179 * <p>If {@code @TestPropertySource} is used as a <em>{@linkplain Repeatable 180 * repeatable}</em> annotation, the following special rules apply. 181 * <ol> 182 * <li>All {@code @TestPropertySource} annotations at a given level in the 183 * test class hierarchy (i.e., directly present or meta-present on a test 184 * class) are considered to be <em>local</em> annotations, in contrast to 185 * {@code @TestPropertySource} annotations that are inherited from a 186 * superclass.</li> 187 * <li>All local {@code @TestPropertySource} annotations must declare the 188 * same value for the {@code inheritLocations} flag.</li> 189 * <li>The {@code inheritLocations} flag is not taken into account between 190 * local {@code @TestPropertySource} annotations. Specifically, the property 191 * source locations for one local annotation will be appended to the list of 192 * property source locations defined by previous local annotations. This 193 * allows a local annotation to extend the list of test property source 194 * locations, potentially overriding individual properties.</li> 195 * </ol> 196 * @see #locations 197 */ 198 boolean inheritLocations() default true; 199 200 /** 201 * <em>Inlined properties</em> in the form of <em>key-value</em> pairs that 202 * should be added to the Spring 203 * {@link org.springframework.core.env.Environment Environment} before the 204 * {@code ApplicationContext} is loaded for the test. All key-value pairs 205 * will be added to the enclosing {@code Environment} as a single test 206 * {@code PropertySource} with the highest precedence. 207 * <h3>Supported Syntax</h3> 208 * <p>The supported syntax for key-value pairs is the same as the 209 * syntax defined for entries in a Java 210 * {@linkplain java.util.Properties#load(java.io.Reader) properties file}: 211 * <ul> 212 * <li>{@code "key=value"}</li> 213 * <li>{@code "key:value"}</li> 214 * <li>{@code "key value"}</li> 215 * </ul> 216 * <h3>Precedence</h3> 217 * <p>Properties declared via this attribute have higher precedence than 218 * properties loaded from resource {@link #locations}. 219 * <p>This attribute may be used in conjunction with {@link #value} 220 * <em>or</em> {@link #locations}. 221 * @see #inheritProperties 222 * @see #locations 223 * @see org.springframework.core.env.PropertySource 224 */ 225 String[] properties() default {}; 226 227 /** 228 * Whether or not inlined test {@link #properties} from superclasses should 229 * be <em>inherited</em>. 230 * <p>The default value is {@code true}, which means that a test class will 231 * <em>inherit</em> inlined properties defined by a superclass. Specifically, 232 * the inlined properties for a test class will be appended to the list of 233 * inlined properties defined by a superclass. Thus, subclasses have the 234 * option of <em>extending</em> the list of inlined test properties. 235 * <p>If {@code inheritProperties} is set to {@code false}, the inlined 236 * properties for the test class will <em>shadow</em> and effectively 237 * replace any inlined properties defined by a superclass. 238 * <p>In the following example, the {@code ApplicationContext} for 239 * {@code BaseTest} will be loaded using only the inlined {@code key1} 240 * property. In contrast, the {@code ApplicationContext} for 241 * {@code ExtendedTest} will be loaded using the inlined {@code key1} 242 * <strong>and</strong> {@code key2} properties. 243 * <pre class="code"> 244 * @TestPropertySource(properties = "key1 = value1") 245 * @ContextConfiguration 246 * public class BaseTest { 247 * // ... 248 * } 249 * @TestPropertySource(properties = "key2 = value2") 250 * @ContextConfiguration 251 * public class ExtendedTest extends BaseTest { 252 * // ... 253 * }</pre> 254 * <p>If {@code @TestPropertySource} is used as a <em>{@linkplain Repeatable 255 * repeatable}</em> annotation, the following special rules apply. 256 * <ol> 257 * <li>All {@code @TestPropertySource} annotations at a given level in the 258 * test class hierarchy (i.e., directly present or meta-present on a test 259 * class) are considered to be <em>local</em> annotations, in contrast to 260 * {@code @TestPropertySource} annotations that are inherited from a 261 * superclass.</li> 262 * <li>All local {@code @TestPropertySource} annotations must declare the 263 * same value for the {@code inheritProperties} flag.</li> 264 * <li>The {@code inheritProperties} flag is not taken into account between 265 * local {@code @TestPropertySource} annotations. Specifically, inlined 266 * properties for one local annotation will be appended to the list of 267 * inlined properties defined by previous local annotations. This allows a 268 * local annotation to extend the list of inlined properties, potentially 269 * overriding individual properties.</li> 270 * </ol> 271 * @see #properties 272 */ 273 boolean inheritProperties() default true; 274 275}