All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.test.context.TestPropertySource Maven / Gradle / Ivy

There is a newer version: 6.1.13
Show newest version
/*
 * Copyright 2002-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.test.context;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;
import org.springframework.core.io.support.PropertySourceFactory;

/**
 * {@code @TestPropertySource} is a class-level annotation that is used to
 * configure the {@link #locations} of properties files and inlined
 * {@link #properties} to be added to the {@code Environment}'s set of
 * {@code PropertySources} for an
 * {@link org.springframework.context.ApplicationContext ApplicationContext}
 * for integration tests.
 *
 * 

Precedence

*

Test property sources have higher precedence than those loaded from the * operating system's environment or Java system properties as well as property * sources added by the application declaratively via * {@link org.springframework.context.annotation.PropertySource @PropertySource} * or programmatically (e.g., via an * {@link org.springframework.context.ApplicationContextInitializer ApplicationContextInitializer} * or some other means). Thus, test property sources can be used to selectively * override properties defined in system and application property sources. * Furthermore, inlined {@link #properties} have higher precedence than * properties loaded from resource {@link #locations}. Note, however, that * properties registered via {@link DynamicPropertySource @DynamicPropertySource} * have higher precedence than those loaded via {@code @TestPropertySource}. * *

Default Properties File Detection

*

If {@code @TestPropertySource} is declared as an empty annotation * (i.e., without explicit values for {@link #locations} or {@link #properties}), * an attempt will be made to detect a default properties file relative * to the class that declared the annotation. For example, if the annotated test * class is {@code com.example.MyTest}, the corresponding default properties file * is {@code "classpath:com/example/MyTest.properties"}. If the default cannot be * detected, an {@link IllegalStateException} will be thrown. * *

Enabling @TestPropertySource

*

{@code @TestPropertySource} is enabled if the configured * {@linkplain ContextConfiguration#loader context loader} honors it. Every * {@code SmartContextLoader} that is a subclass of either * {@link org.springframework.test.context.support.AbstractGenericContextLoader AbstractGenericContextLoader} or * {@link org.springframework.test.context.web.AbstractGenericWebContextLoader AbstractGenericWebContextLoader} * provides automatic support for {@code @TestPropertySource}, and this includes * every {@code SmartContextLoader} provided by the Spring TestContext Framework. * *

Miscellaneous

*
    *
  • Typically, {@code @TestPropertySource} will be used in conjunction with * {@link ContextConfiguration @ContextConfiguration}.
  • *
  • {@code @TestPropertySource} can be used as a {@linkplain Repeatable * repeatable} annotation.
  • *
  • This annotation may be used as a meta-annotation to create * custom composed annotations, but caution should be taken if * this annotation and {@code @ContextConfiguration} are combined on a composed * annotation since the {@code locations} and {@code inheritLocations} attributes * of both annotations can lead to ambiguity during the attribute resolution * process. Note, however, that ambiguity can be avoided via explicit annotation * attribute overrides using {@link AliasFor @AliasFor}.
  • *
  • As of Spring Framework 5.3, this annotation will be inherited from an * enclosing test class by default. See * {@link NestedTestConfiguration @NestedTestConfiguration} for details.
  • *
* * @author Sam Brannen * @since 4.1 * @see ContextConfiguration * @see DynamicPropertySource * @see org.springframework.core.env.Environment * @see org.springframework.core.env.PropertySource * @see org.springframework.context.annotation.PropertySource */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Repeatable(TestPropertySources.class) public @interface TestPropertySource { /** * Alias for {@link #locations}. *

This attribute may not be used in conjunction with * {@link #locations}, but it may be used instead of {@link #locations}. * @see #locations */ @AliasFor("locations") String[] value() default {}; /** * The resource locations of properties files to be loaded into the * {@code Environment}'s set of {@code PropertySources}. *

Each location will be added to the enclosing {@code Environment} as its * own property source, in the order declared (or in the order in which resource * locations are resolved when location wildcards are used). *

Supported File Formats

*

By default, both traditional and XML-based properties file formats are * supported — for example, {@code "classpath:/com/example/test.properties"} * or {@code "file:/path/to/file.xml"}. To support a different file format, * configure an appropriate {@link #factory() PropertySourceFactory}. *

Path Resource Semantics

*

Each path will be interpreted as a Spring * {@link org.springframework.core.io.Resource Resource}. A plain path * — for example, {@code "test.properties"} — will be treated as a * classpath resource that is relative to the package in which the * test class is defined. A path starting with a slash will be treated as an * absolute classpath resource, for example: * {@code "/org/example/test.xml"}. A path which references a * URL (e.g., a path prefixed with * {@link org.springframework.util.ResourceUtils#CLASSPATH_URL_PREFIX classpath:}, * {@link org.springframework.util.ResourceUtils#FILE_URL_PREFIX file:}, * {@code http:}, etc.) will be loaded using the specified resource protocol. *

Property placeholders in paths (i.e., ${...}) will be * {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) * resolved} against the {@code Environment}. *

As of Spring Framework 6.1, resource location patterns are also * supported — for example, {@code "classpath*:/config/*.properties"}. *

WARNING: a pattern such as {@code "classpath*:/config/*.properties"} * may be effectively equivalent to an explicit enumeration of resource locations such as * {"classpath:/config/mail.properties", classpath:/config/order.properties"}; * however, the two declarations will result in different keys for the context * cache since the pattern cannot be eagerly resolved to concrete locations. * Consequently, to benefit from the context cache you must ensure that you * consistently use either patterns or explicit enumerations of resource * locations within your test suite. *

Default Properties File Detection

*

See the class-level Javadoc for a discussion on detection of defaults. *

Precedence

*

Properties loaded from resource locations have lower precedence than * inlined {@link #properties}. *

This attribute may not be used in conjunction with * {@link #value}, but it may be used instead of {@link #value}. * @see #inheritLocations * @see #value * @see #properties * @see #encoding * @see #factory * @see org.springframework.core.env.PropertySource */ @AliasFor("value") String[] locations() default {}; /** * Whether test property source {@link #locations} from superclasses * and enclosing classes should be inherited. *

The default value is {@code true}, which means that a test class will * inherit property source locations defined by a superclass or * enclosing class. Specifically, the property source locations for a test * class will be appended to the list of property source locations defined * by a superclass or enclosing class. Thus, subclasses and nested classes * have the option of extending the list of test property source * locations. *

If {@code inheritLocations} is set to {@code false}, the property * source locations for the test class will shadow and effectively * replace any property source locations defined by a superclass or * enclosing class. *

In the following example, the {@code ApplicationContext} for * {@code BaseTest} will be loaded using only the {@code "base.properties"} * file as a test property source. In contrast, the {@code ApplicationContext} * for {@code ExtendedTest} will be loaded using the {@code "base.properties"} * and {@code "extended.properties"} files as test property * source locations. *

	 * @TestPropertySource("base.properties")
	 * @ContextConfiguration
	 * public class BaseTest {
	 *   // ...
	 * }
	 *
	 * @TestPropertySource("extended.properties")
	 * @ContextConfiguration
	 * public class ExtendedTest extends BaseTest {
	 *   // ...
	 * }
*

If {@code @TestPropertySource} is used as a {@linkplain Repeatable * repeatable} annotation, the following special rules apply. *

    *
  1. All {@code @TestPropertySource} annotations at a given level in the * test class hierarchy (i.e., directly present or meta-present on a test * class) are considered to be local annotations, in contrast to * {@code @TestPropertySource} annotations that are inherited from a * superclass.
  2. *
  3. All local {@code @TestPropertySource} annotations must declare the * same value for the {@code inheritLocations} flag.
  4. *
  5. The {@code inheritLocations} flag is not taken into account between * local {@code @TestPropertySource} annotations. Specifically, the property * source locations for one local annotation will be appended to the list of * property source locations defined by previous local annotations. This * allows a local annotation to extend the list of test property source * locations, potentially overriding individual properties.
  6. *
* @see #locations */ boolean inheritLocations() default true; /** * Inlined properties in the form of key-value pairs that * should be added to the Spring * {@link org.springframework.core.env.Environment Environment} before the * {@code ApplicationContext} is loaded for the test. All key-value pairs * will be added to the enclosing {@code Environment} as a single test * {@code PropertySource} with the highest precedence. As of Spring Framework * 6.1, multiple key-value pairs may be specified via a single text block. *

Supported Syntax

*

The supported syntax for key-value pairs is the same as the * syntax defined for entries in a Java * {@linkplain java.util.Properties#load(java.io.Reader) properties file}: *

    *
  • {@code "key=value"}
  • *
  • {@code "key:value"}
  • *
  • {@code "key value"}
  • *
*

WARNING: although properties can be defined using any * of the above syntax variants and any number of spaces between the key and * the value, it is recommended that you use one syntax variant and consistent * spacing within your test suite — for example, consider always using * {@code "key = value"} instead of {@code "key= value"}, {@code "key=value"}, * etc. Similarly, if you define inlined properties using text blocks * you should consistently use text blocks for inlined properties throughout * your test suite. The reason is that the exact strings you provide will be * used to determine the key for the context cache. Consequently, to benefit * from the context cache you must ensure that you define inlined properties * consistently. *

Examples

*
	 * // Using an array of strings
	 * @TestPropertySource(properties = {
	 *     "key1 = value1",
	 *     "key2 = value2"
	 * })
	 * @ContextConfiguration
	 * class MyTests {
	 *   // ...
	 * }
*
	 * // Using a single text block
	 * @TestPropertySource(properties = """
	 *     key1 = value1
	 *     key2 = value2
	 *     """
	 * )
	 * @ContextConfiguration
	 * class MyTests {
	 *   // ...
	 * }
*

Precedence

*

Properties declared via this attribute have higher precedence than * properties loaded from resource {@link #locations}. *

This attribute may be used in conjunction with {@link #value} * or {@link #locations}. * @see #inheritProperties * @see #locations * @see org.springframework.core.env.PropertySource */ String[] properties() default {}; /** * Whether inlined test {@link #properties} from superclasses and * enclosing classes should be inherited. *

The default value is {@code true}, which means that a test class will * inherit inlined properties defined by a superclass or enclosing * class. Specifically, the inlined properties for a test class will be * appended to the list of inlined properties defined by a superclass or * enclosing class. Thus, subclasses and nested classes have the option of * extending the list of inlined test properties. *

If {@code inheritProperties} is set to {@code false}, the inlined * properties for the test class will shadow and effectively * replace any inlined properties defined by a superclass or enclosing class. *

In the following example, the {@code ApplicationContext} for * {@code BaseTest} will be loaded using only the inlined {@code key1} * property. In contrast, the {@code ApplicationContext} for * {@code ExtendedTest} will be loaded using the inlined {@code key1} * and {@code key2} properties. *

	 * @TestPropertySource(properties = "key1 = value1")
	 * @ContextConfiguration
	 * public class BaseTest {
	 *   // ...
	 * }
	 * @TestPropertySource(properties = "key2 = value2")
	 * @ContextConfiguration
	 * public class ExtendedTest extends BaseTest {
	 *   // ...
	 * }
*

If {@code @TestPropertySource} is used as a {@linkplain Repeatable * repeatable} annotation, the following special rules apply. *

    *
  1. All {@code @TestPropertySource} annotations at a given level in the * test class hierarchy (i.e., directly present or meta-present on a test * class) are considered to be local annotations, in contrast to * {@code @TestPropertySource} annotations that are inherited from a * superclass or enclosing class.
  2. *
  3. All local {@code @TestPropertySource} annotations must declare the * same value for the {@code inheritProperties} flag.
  4. *
  5. The {@code inheritProperties} flag is not taken into account between * local {@code @TestPropertySource} annotations. Specifically, inlined * properties for one local annotation will be appended to the list of * inlined properties defined by previous local annotations. This allows a * local annotation to extend the list of inlined properties, potentially * overriding individual properties.
  6. *
* @see #properties */ boolean inheritProperties() default true; /** * Specify the character encoding for the given {@linkplain #locations resources} * — for example, "UTF-8". *

If not specified, the default character encoding of the JVM will be used. * @since 6.1 */ String encoding() default ""; /** * Specify a custom {@link PropertySourceFactory}, if any. *

By default, a factory for standard resource files will be used which * supports {@code *.properties} and {@code *.xml} file formats for * {@link java.util.Properties}. * @since 6.1 * @see org.springframework.core.io.support.DefaultPropertySourceFactory * @see org.springframework.core.io.support.ResourcePropertySource */ Class factory() default PropertySourceFactory.class; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy