001/*
002 * Copyright 2012-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 *      http://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.boot.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.boot.SpringApplication;
027import org.springframework.boot.SpringBootConfiguration;
028import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
029import org.springframework.boot.context.embedded.LocalServerPort;
030import org.springframework.context.ApplicationContext;
031import org.springframework.context.annotation.Configuration;
032import org.springframework.core.annotation.AliasFor;
033import org.springframework.core.env.Environment;
034import org.springframework.test.context.BootstrapWith;
035import org.springframework.test.context.ContextConfiguration;
036import org.springframework.test.context.ContextLoader;
037import org.springframework.web.context.WebApplicationContext;
038
039/**
040 * Annotation that can be specified on a test class that runs Spring Boot based tests.
041 * Provides the following features over and above the regular <em>Spring TestContext
042 * Framework</em>:
043 * <ul>
044 * <li>Uses {@link SpringBootContextLoader} as the default {@link ContextLoader} when no
045 * specific {@link ContextConfiguration#loader() @ContextConfiguration(loader=...)} is
046 * defined.</li>
047 * <li>Automatically searches for a
048 * {@link SpringBootConfiguration @SpringBootConfiguration} when nested
049 * {@code @Configuration} is not used, and no explicit {@link #classes() classes} are
050 * specified.</li>
051 * <li>Allows custom {@link Environment} properties to be defined using the
052 * {@link #properties() properties attribute}.</li>
053 * <li>Provides support for different {@link #webEnvironment() webEnvironment} modes,
054 * including the ability to start a fully running container listening on a
055 * {@link WebEnvironment#DEFINED_PORT defined} or {@link WebEnvironment#RANDOM_PORT
056 * random} port.</li>
057 * <li>Registers a {@link org.springframework.boot.test.web.client.TestRestTemplate
058 * TestRestTemplate} bean for use in web tests that are using a fully running container.
059 * </li>
060 * </ul>
061 *
062 * @author Phillip Webb
063 * @author Andy Wilkinson
064 * @since 1.4.0
065 * @see ContextConfiguration
066 */
067@Target(ElementType.TYPE)
068@Retention(RetentionPolicy.RUNTIME)
069@Documented
070@Inherited
071@BootstrapWith(SpringBootTestContextBootstrapper.class)
072public @interface SpringBootTest {
073
074        /**
075         * Alias for {@link #properties()}.
076         * @return the properties to apply
077         */
078        @AliasFor("properties")
079        String[] value() default {};
080
081        /**
082         * Properties in form {@literal key=value} that should be added to the Spring
083         * {@link Environment} before the test runs.
084         * @return the properties to add
085         */
086        @AliasFor("value")
087        String[] properties() default {};
088
089        /**
090         * The <em>annotated classes</em> to use for loading an
091         * {@link org.springframework.context.ApplicationContext ApplicationContext}. Can also
092         * be specified using
093         * {@link ContextConfiguration#classes() @ContextConfiguration(classes=...)}. If no
094         * explicit classes are defined the test will look for nested
095         * {@link Configuration @Configuration} classes, before falling back to a
096         * {@link SpringBootConfiguration} search.
097         * @see ContextConfiguration#classes()
098         * @return the annotated classes used to load the application context
099         */
100        Class<?>[] classes() default {};
101
102        /**
103         * The type of web environment to create when applicable. Defaults to
104         * {@link WebEnvironment#MOCK}.
105         * @return the type of web environment
106         */
107        WebEnvironment webEnvironment() default WebEnvironment.MOCK;
108
109        /**
110         * An enumeration web environment modes.
111         */
112        enum WebEnvironment {
113
114                /**
115                 * Creates a {@link WebApplicationContext} with a mock servlet environment or a
116                 * regular {@link ApplicationContext} if servlet APIs are not on the classpath.
117                 */
118                MOCK(false),
119
120                /**
121                 * Creates an {@link EmbeddedWebApplicationContext} and sets a
122                 * {@code server.port=0} {@link Environment} property (which usually triggers
123                 * listening on a random port). Often used in conjunction with a
124                 * {@link LocalServerPort} injected field on the test.
125                 */
126                RANDOM_PORT(true),
127
128                /**
129                 * Creates an {@link EmbeddedWebApplicationContext} without defining any
130                 * {@code server.port=0} {@link Environment} property.
131                 */
132                DEFINED_PORT(true),
133
134                /**
135                 * Creates an {@link ApplicationContext} and sets
136                 * {@link SpringApplication#setWebEnvironment(boolean)} to {@code false}.
137                 */
138                NONE(false);
139
140                private final boolean embedded;
141
142                WebEnvironment(boolean embedded) {
143                        this.embedded = embedded;
144                }
145
146                /**
147                 * Return if the environment uses an {@link EmbeddedWebApplicationContext}.
148                 * @return if an {@link EmbeddedWebApplicationContext} is used.
149                 */
150                public boolean isEmbedded() {
151                        return this.embedded;
152                }
153
154        }
155
156}