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 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.Retention; 023import java.lang.annotation.RetentionPolicy; 024import java.lang.annotation.Target; 025 026import org.springframework.core.annotation.AliasFor; 027 028/** 029 * {@code @TestPropertySource} is a class-level annotation that is used to 030 * configure the {@link #locations} of properties files and inlined 031 * {@link #properties} to be added to the {@code Environment}'s set of 032 * {@code PropertySources} for an 033 * {@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 the 038 * operating system's environment or Java system properties as well as property 039 * sources added by the application declaratively via 040 * {@link org.springframework.context.annotation.PropertySource @PropertySource} 041 * or programmatically (e.g., via an 042 * {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer} 043 * or some other means). Thus, test property sources can be used to selectively 044 * override properties defined in system and application property sources. 045 * Furthermore, inlined {@link #properties} have higher precedence than 046 * 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> annotation 050 * (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 relative 052 * to the class that declared the annotation. For example, if the annotated test 053 * class is {@code com.example.MyTest}, the corresponding default properties file 054 * is {@code "classpath:com/example/MyTest.properties"}. If the default cannot be 055 * detected, an {@link IllegalStateException} will be thrown. 056 * 057 * <h3>Enabling @TestPropertySource</h3> 058 * <p>{@code @TestPropertySource} is enabled if the configured 059 * {@linkplain ContextConfiguration#loader context loader} honors it. Every 060 * {@code SmartContextLoader} that is a subclass of either 061 * {@link org.springframework.test.context.support.AbstractGenericContextLoader AbstractGenericContextLoader} or 062 * {@link org.springframework.test.context.web.AbstractGenericWebContextLoader AbstractGenericWebContextLoader} 063 * provides automatic support for {@code @TestPropertySource}, and this includes 064 * 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 with 069 * {@link ContextConfiguration @ContextConfiguration}.</li> 070 * <li>This annotation may be used as a <em>meta-annotation</em> to create 071 * custom <em>composed annotations</em>; however, caution should be taken if 072 * this annotation and {@code @ContextConfiguration} are combined on a composed 073 * annotation since the {@code locations} and {@code inheritLocations} attributes 074 * of both annotations can lead to ambiguity during the attribute resolution 075 * process.</li> 076 * </ul> 077 * 078 * @author Sam Brannen 079 * @since 4.1 080 * @see ContextConfiguration 081 * @see org.springframework.core.env.Environment 082 * @see org.springframework.core.env.PropertySource 083 * @see org.springframework.context.annotation.PropertySource 084 */ 085@Target(ElementType.TYPE) 086@Retention(RetentionPolicy.RUNTIME) 087@Documented 088@Inherited 089public @interface TestPropertySource { 090 091 /** 092 * Alias for {@link #locations}. 093 * <p>This attribute may <strong>not</strong> be used in conjunction with 094 * {@link #locations}, but it may be used <em>instead</em> of {@link #locations}. 095 * @see #locations 096 */ 097 @AliasFor("locations") 098 String[] value() default {}; 099 100 /** 101 * The resource locations of properties files to be loaded into the 102 * {@code Environment}'s set of {@code PropertySources}. Each location 103 * will be added to the enclosing {@code Environment} as its own property 104 * source, in the order declared. 105 * <h3>Supported File Formats</h3> 106 * <p>Both traditional and XML-based properties file formats are supported 107 * — 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 Spring 111 * {@link org.springframework.core.io.Resource Resource}. A plain path 112 * — for example, {@code "test.properties"} — will be treated as a 113 * classpath resource that is <em>relative</em> to the package in which the 114 * test class is defined. A path starting with a slash will be treated as an 115 * <em>absolute</em> classpath resource, for example: 116 * {@code "/org/example/test.xml"}. A path which references a 117 * URL (e.g., a path prefixed with 118 * {@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>**/*.properties</code>) 122 * are not permitted: each location must evaluate to exactly one 123 * {@code .properties} or {@code .xml} resource. Property placeholders 124 * in paths (i.e., <code>${...}</code>) will be 125 * {@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 than 131 * inlined {@link #properties}. 132 * <p>This attribute may <strong>not</strong> be used in conjunction with 133 * {@link #value}, but it may be used <em>instead</em> of {@link #value}. 134 * @see #inheritLocations 135 * @see #value 136 * @see #properties 137 * @see org.springframework.core.env.PropertySource 138 */ 139 @AliasFor("value") 140 String[] locations() default {}; 141 142 /** 143 * Whether or not test property source {@link #locations} from superclasses 144 * should be <em>inherited</em>. 145 * <p>The default value is {@code true}, which means that a test class will 146 * <em>inherit</em> property source locations defined by a superclass. 147 * Specifically, the property source locations for a test class will be 148 * 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 test 150 * property source locations. 151 * <p>If {@code inheritLocations} is set to {@code false}, the property 152 * source locations for the test class will <em>shadow</em> and effectively 153 * replace any property source locations defined by a superclass. 154 * <p>In the following example, the {@code ApplicationContext} for 155 * {@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 property 159 * source locations. 160 * <pre class="code"> 161 * @TestPropertySource("base.properties") 162 * @ContextConfiguration 163 * public class BaseTest { 164 * // ... 165 * } 166 * 167 * @TestPropertySource("extended.properties") 168 * @ContextConfiguration 169 * public class ExtendedTest extends BaseTest { 170 * // ... 171 * } 172 * </pre> 173 * 174 * @see #locations 175 */ 176 boolean inheritLocations() default true; 177 178 /** 179 * <em>Inlined properties</em> in the form of <em>key-value</em> pairs that 180 * should be added to the Spring 181 * {@link org.springframework.core.env.Environment Environment} before the 182 * {@code ApplicationContext} is loaded for the test. All key-value pairs 183 * will be added to the enclosing {@code Environment} as a single test 184 * {@code PropertySource} with the highest precedence. 185 * <h3>Supported Syntax</h3> 186 * <p>The supported syntax for key-value pairs is the same as the 187 * syntax defined for entries in a Java 188 * {@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 than 196 * 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 #inheritProperties 200 * @see #locations 201 * @see org.springframework.core.env.PropertySource 202 */ 203 String[] properties() default {}; 204 205 /** 206 * Whether or not inlined test {@link #properties} from superclasses should 207 * be <em>inherited</em>. 208 * <p>The default value is {@code true}, which means that a test class will 209 * <em>inherit</em> inlined properties defined by a superclass. Specifically, 210 * the inlined properties for a test class will be appended to the list of 211 * inlined properties defined by a superclass. Thus, subclasses have the 212 * option of <em>extending</em> the list of inlined test properties. 213 * <p>If {@code inheritProperties} is set to {@code false}, the inlined 214 * properties for the test class will <em>shadow</em> and effectively 215 * replace any inlined properties defined by a superclass. 216 * <p>In the following example, the {@code ApplicationContext} for 217 * {@code BaseTest} will be loaded using only the inlined {@code key1} 218 * property. In contrast, the {@code ApplicationContext} for 219 * {@code ExtendedTest} will be loaded using the inlined {@code key1} 220 * <strong>and</strong> {@code key2} properties. 221 * <pre class="code"> 222 * @TestPropertySource(properties = "key1 = value1") 223 * @ContextConfiguration 224 * public class BaseTest { 225 * // ... 226 * } 227 * @TestPropertySource(properties = "key2 = value2") 228 * @ContextConfiguration 229 * public class ExtendedTest extends BaseTest { 230 * // ... 231 * } 232 * </pre> 233 * @see #properties 234 */ 235 boolean inheritProperties() default true; 236 237}