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