001/*002 * Copyright 2002-2016 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 at007 *008 * https://www.apache.org/licenses/LICENSE-2.0009 *010 * Unless required by applicable law or agreed to in writing, software011 * 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 and014 * limitations under the License.015 */016017package org.springframework.test.context;018019import java.lang.annotation.Documented;020import java.lang.annotation.ElementType;021import java.lang.annotation.Inherited;022import java.lang.annotation.Retention;023import java.lang.annotation.RetentionPolicy;024import java.lang.annotation.Target;025026import org.springframework.core.annotation.AliasFor;027028/**029 * {@code @TestPropertySource} is a class-level annotation that is used to030 * configure the {@link #locations} of properties files and inlined031 * {@link #properties} to be added to the {@code Environment}'s set of032 * {@code PropertySources} for an033 * {@link org.springframework.context.ApplicationContext ApplicationContext}034 * for integration tests.035 *036 * <h3>Precedence</h3>037 * <p>Test property sources have higher precedence than those loaded from the038 * operating system's environment or Java system properties as well as property039 * sources added by the application declaratively via040 * {@link org.springframework.context.annotation.PropertySource @PropertySource}041 * or programmatically (e.g., via an042 * {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer}043 * or some other means). Thus, test property sources can be used to selectively044 * override properties defined in system and application property sources.045 * Furthermore, inlined {@link #properties} have higher precedence than046 * properties loaded from resource {@link #locations}.047 *048 * <h3>Default Properties File Detection</h3>049 * <p>If {@code @TestPropertySource} is declared as an <em>empty</em> annotation050 * (i.e., without explicit values for {@link #locations} or {@link #properties}),051 * an attempt will be made to detect a <em>default</em> properties file relative052 * to the class that declared the annotation. For example, if the annotated test053 * class is {@code com.example.MyTest}, the corresponding default properties file054 * is {@code "classpath:com/example/MyTest.properties"}. If the default cannot be055 * detected, an {@link IllegalStateException} will be thrown.056 *057 * <h3>Enabling &#064;TestPropertySource</h3>058 * <p>{@code @TestPropertySource} is enabled if the configured059 * {@linkplain ContextConfiguration#loader context loader} honors it. Every060 * {@code SmartContextLoader} that is a subclass of either061 * {@link org.springframework.test.context.support.AbstractGenericContextLoader AbstractGenericContextLoader} or062 * {@link org.springframework.test.context.web.AbstractGenericWebContextLoader AbstractGenericWebContextLoader}063 * provides automatic support for {@code @TestPropertySource}, and this includes064 * every {@code SmartContextLoader} provided by the Spring TestContext Framework.065 *066 * <h3>Miscellaneous</h3>067 * <ul>068 * <li>Typically, {@code @TestPropertySource} will be used in conjunction with069 * {@link ContextConfiguration @ContextConfiguration}.</li>070 * <li>This annotation may be used as a <em>meta-annotation</em> to create071 * custom <em>composed annotations</em>; however, caution should be taken if072 * this annotation and {@code @ContextConfiguration} are combined on a composed073 * annotation since the {@code locations} and {@code inheritLocations} attributes074 * of both annotations can lead to ambiguity during the attribute resolution075 * process.</li>076 * </ul>077 *078 * @author Sam Brannen079 * @since 4.1080 * @see ContextConfiguration081 * @see org.springframework.core.env.Environment082 * @see org.springframework.core.env.PropertySource083 * @see org.springframework.context.annotation.PropertySource084 */085@Target(ElementType.TYPE)086@Retention(RetentionPolicy.RUNTIME)087@Documented088@Inherited089public @interface TestPropertySource {090091 /**092 * Alias for {@link #locations}.093 * <p>This attribute may <strong>not</strong> be used in conjunction with094 * {@link #locations}, but it may be used <em>instead</em> of {@link #locations}.095 * @see #locations096 */097 @AliasFor("locations")098 String[] value() default {};099100 /**101 * The resource locations of properties files to be loaded into the102 * {@code Environment}'s set of {@code PropertySources}. Each location103 * will be added to the enclosing {@code Environment} as its own property104 * source, in the order declared.105 * <h3>Supported File Formats</h3>106 * <p>Both traditional and XML-based properties file formats are supported107 * &mdash; for example, {@code "classpath:/com/example/test.properties"}108 * or {@code "file:/path/to/file.xml"}.109 * <h3>Path Resource Semantics</h3>110 * <p>Each path will be interpreted as a Spring111 * {@link org.springframework.core.io.Resource Resource}. A plain path112 * &mdash; for example, {@code "test.properties"} &mdash; will be treated as a113 * classpath resource that is <em>relative</em> to the package in which the114 * test class is defined. A path starting with a slash will be treated as an115 * <em>absolute</em> classpath resource, for example:116 * {@code "/org/example/test.xml"}. A path which references a117 * URL (e.g., a path prefixed with118 * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX classpath:},119 * {@link org.springframework.util.ResourceUtils#FILE_URL_PREFIX file:},120 * {@code http:}, etc.) will be loaded using the specified resource protocol.121 * Resource location wildcards (e.g. <code>*&#42;/*.properties</code>)122 * are not permitted: each location must evaluate to exactly one123 * {@code .properties} or {@code .xml} resource. Property placeholders124 * in paths (i.e., <code>${...}</code>) will be125 * {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) resolved}126 * against the {@code Environment}.127 * <h3>Default Properties File Detection</h3>128 * <p>See the class-level Javadoc for a discussion on detection of defaults.129 * <h3>Precedence</h3>130 * <p>Properties loaded from resource locations have lower precedence than131 * inlined {@link #properties}.132 * <p>This attribute may <strong>not</strong> be used in conjunction with133 * {@link #value}, but it may be used <em>instead</em> of {@link #value}.134 * @see #inheritLocations135 * @see #value136 * @see #properties137 * @see org.springframework.core.env.PropertySource138 */139 @AliasFor("value")140 String[] locations() default {};141142 /**143 * Whether or not test property source {@link #locations} from superclasses144 * should be <em>inherited</em>.145 * <p>The default value is {@code true}, which means that a test class will146 * <em>inherit</em> property source locations defined by a superclass.147 * Specifically, the property source locations for a test class will be148 * appended to the list of property source locations defined by a superclass.149 * Thus, subclasses have the option of <em>extending</em> the list of test150 * property source locations.151 * <p>If {@code inheritLocations} is set to {@code false}, the property152 * source locations for the test class will <em>shadow</em> and effectively153 * replace any property source locations defined by a superclass.154 * <p>In the following example, the {@code ApplicationContext} for155 * {@code BaseTest} will be loaded using only the {@code "base.properties"}156 * file as a test property source. In contrast, the {@code ApplicationContext}157 * for {@code ExtendedTest} will be loaded using the {@code "base.properties"}158 * <strong>and</strong> {@code "extended.properties"} files as test property159 * source locations.160 * <pre class="code">161 * &#064;TestPropertySource(&quot;base.properties&quot;)162 * &#064;ContextConfiguration163 * public class BaseTest {164 * // ...165 * }166 *167 * &#064;TestPropertySource(&quot;extended.properties&quot;)168 * &#064;ContextConfiguration169 * public class ExtendedTest extends BaseTest {170 * // ...171 * }172 * </pre>173 *174 * @see #locations175 */176 boolean inheritLocations() default true;177178 /**179 * <em>Inlined properties</em> in the form of <em>key-value</em> pairs that180 * should be added to the Spring181 * {@link org.springframework.core.env.Environment Environment} before the182 * {@code ApplicationContext} is loaded for the test. All key-value pairs183 * will be added to the enclosing {@code Environment} as a single test184 * {@code PropertySource} with the highest precedence.185 * <h3>Supported Syntax</h3>186 * <p>The supported syntax for key-value pairs is the same as the187 * syntax defined for entries in a Java188 * {@linkplain java.util.Properties#load(java.io.Reader) properties file}:189 * <ul>190 * <li>{@code "key=value"}</li>191 * <li>{@code "key:value"}</li>192 * <li>{@code "key value"}</li>193 * </ul>194 * <h3>Precedence</h3>195 * <p>Properties declared via this attribute have higher precedence than196 * properties loaded from resource {@link #locations}.197 * <p>This attribute may be used in conjunction with {@link #value}198 * <em>or</em> {@link #locations}.199 * @see #inheritProperties200 * @see #locations201 * @see org.springframework.core.env.PropertySource202 */203 String[] properties() default {};204205 /**206 * Whether or not inlined test {@link #properties} from superclasses should207 * be <em>inherited</em>.208 * <p>The default value is {@code true}, which means that a test class will209 * <em>inherit</em> inlined properties defined by a superclass. Specifically,210 * the inlined properties for a test class will be appended to the list of211 * inlined properties defined by a superclass. Thus, subc