Commit bbc91cc0 authored by Phillip Webb's avatar Phillip Webb

Add @WebMvcTest annotation

Add @WebMvcTest and @AutoConfigureMockMvc annotations to allow testing
of an application "slice" that only deals with Spring MVC.

See gh-4901
parent 0bd89017
...@@ -29,16 +29,43 @@ ...@@ -29,16 +29,43 @@
<artifactId>spring-boot-autoconfigure</artifactId> <artifactId>spring-boot-autoconfigure</artifactId>
</dependency> </dependency>
<!-- Optional --> <!-- Optional -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.19</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-htmlunit-driver</artifactId>
<version>2.52.0</version>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.aspectj</groupId> <groupId>org.aspectj</groupId>
...@@ -50,6 +77,11 @@ ...@@ -50,6 +77,11 @@
<artifactId>aspectjweaver</artifactId> <artifactId>aspectjweaver</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
......
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.gargoylesoftware.htmlunit.WebClient;
import org.openqa.selenium.WebDriver;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
/**
* Annotation that can be applied to a test class to enable and configure
* auto-configuration of {@link MockMvc}.
*
* @author Phillip Webb
* @since 1.4.0
* @see MockMvcAutoConfiguration
* @see SpringBootMockMvcConfigurer
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@ImportAutoConfiguration({ MockMvcAutoConfiguration.class,
MockMvcWebClientAutoConfiguration.class,
MockMvcWebDriverAutoConfiguration.class })
@PropertyMapping("spring.test.mockmvc")
public @interface AutoConfigureMockMvc {
/**
* If filters from the application context should be registered with MockMVC. Defaults
* to {@code true}.
*/
boolean addFilters() default true;
/**
* If {@link MvcResult} information should always be printed after each MockMVC
* invocation. Defaults to {@code true}.
*/
boolean alwaysPrint() default true;
/**
* If a {@link WebClient} should be auto-configured when HtmlUnit is on the classpath.
* Defaults to {@code true}.
*/
@PropertyMapping("webclient.enabled")
boolean webClientEnabled() default true;
/**
* If a {@link WebDriver} should be auto-configured when Selenium is on the classpath.
* Defaults to {@code true}.
*/
@PropertyMapping("webdriver.enabled")
boolean webDriverEnabled() default true;
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
/**
* {@link ImportAutoConfiguration Auto-configuration imports} for typical Spring MVC
* tests. Most tests should consider using {@link WebMvcTest @WebMvcTest} rather than
* using this annotation directly.
*
* @author Phillip Webb
* @since 1.4.0
* @see WebMvcTest
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ImportAutoConfiguration({ WebMvcAutoConfiguration.class, GsonAutoConfiguration.class,
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class })
public @interface ImportWebMvcAutoConfiguration {
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* Auto-configuration for {@link MockMvc}.
*
* @author Phillip Webb
* @see ImportWebMvcAutoConfiguration
*/
@Configuration
@ConditionalOnWebApplication
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
@EnableConfigurationProperties
class MockMvcAutoConfiguration {
@Autowired
private WebApplicationContext context;
@Bean
@ConditionalOnMissingBean(MockMvcBuilder.class)
public DefaultMockMvcBuilder mockMvcBuilder() {
return MockMvcBuilders.webAppContextSetup(this.context)
.apply(mockMvcConfigurer());
}
@Bean
@ConfigurationProperties("spring.test.mockmvc")
public SpringBootMockMvcConfigurer mockMvcConfigurer() {
return new SpringBootMockMvcConfigurer(this.context);
}
@Bean
@ConditionalOnMissingBean
public MockMvc mockMvc(MockMvcBuilder builder) {
return builder.build();
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import com.gargoylesoftware.htmlunit.WebClient;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.web.htmlunit.LocalHostWebClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder;
/**
* Auto-configuration for HtmlUnit {@link WebClient} MockMVC integration.
*
* @author Phillip Webb
*/
@Configuration
@ConditionalOnClass(WebClient.class)
@AutoConfigureAfter(MockMvcAutoConfiguration.class)
@ConditionalOnProperty(prefix = "spring.test.webmvc.webclient", name = "enabled", matchIfMissing = true)
class MockMvcWebClientAutoConfiguration {
private final Environment environment;
MockMvcWebClientAutoConfiguration(Environment environment) {
this.environment = environment;
}
@Bean
@ConditionalOnMissingBean({ WebClient.class, MockMvcWebClientBuilder.class })
@ConditionalOnBean(MockMvc.class)
public MockMvcWebClientBuilder mockMvcWebClientBuilder(MockMvc mockMvc) {
return MockMvcWebClientBuilder.mockMvcSetup(mockMvc)
.withDelegate(new LocalHostWebClient(this.environment));
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(MockMvcWebClientBuilder.class)
public WebClient htmlUnitWebClient(MockMvcWebClientBuilder builder) {
return builder.build();
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.web.htmlunit.webdriver.LocalHostWebConnectionHtmlUnitDriver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
/**
* Auto-configuration for Selenium {@link WebDriver} MockMVC integration.
*
* @author Phillip Webb
*/
@Configuration
@ConditionalOnClass(HtmlUnitDriver.class)
@AutoConfigureAfter(MockMvcAutoConfiguration.class)
@ConditionalOnProperty(prefix = "spring.test.webmvc.webdriver", name = "enabled", matchIfMissing = true)
class MockMvcWebDriverAutoConfiguration {
private final Environment environment;
MockMvcWebDriverAutoConfiguration(Environment environment) {
this.environment = environment;
}
@Bean
@ConditionalOnMissingBean({ WebDriver.class, MockMvcHtmlUnitDriverBuilder.class })
@ConditionalOnBean(MockMvc.class)
public MockMvcHtmlUnitDriverBuilder mockMvcHtmlUnitDriverBuilder(MockMvc mockMvc) {
return MockMvcHtmlUnitDriverBuilder.mockMvcSetup(mockMvc)
.withDelegate(new LocalHostWebConnectionHtmlUnitDriver(this.environment,
BrowserVersion.CHROME));
}
@Bean
@ConditionalOnMissingBean(WebDriver.class)
@ConditionalOnBean(MockMvcHtmlUnitDriverBuilder.class)
public HtmlUnitDriver htmlUnitDriver(MockMvcHtmlUnitDriverBuilder builder) {
return builder.build();
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.util.Collection;
import javax.servlet.Filter;
import org.springframework.boot.context.embedded.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.ServletContextInitializerBeans;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
/**
* {@link MockMvcConfigurer} for a typical Spring Boot application. Usually applied
* automatically via {@link AutoConfigureMockMvc @AutoConfigureMockMvc}, but may also be
* used directly.
*
* @author Phillip Webb
* @since 1.4.0
*/
public class SpringBootMockMvcConfigurer implements MockMvcConfigurer {
private final WebApplicationContext context;
private boolean addFilters = true;
private boolean alwaysPrint = true;
/**
* Create a new {@link SpringBootMockMvcConfigurer} instance.
* @param context the source application context
*/
public SpringBootMockMvcConfigurer(WebApplicationContext context) {
Assert.notNull(context, "Context must not be null");
this.context = context;
}
@Override
public void afterConfigurerAdded(ConfigurableMockMvcBuilder<?> builder) {
if (this.addFilters) {
addFilters(builder);
}
if (this.alwaysPrint) {
builder.alwaysDo(MockMvcResultHandlers.print(System.out));
}
}
@Override
public RequestPostProcessor beforeMockMvcCreated(
ConfigurableMockMvcBuilder<?> builder, WebApplicationContext context) {
return null;
}
private void addFilters(ConfigurableMockMvcBuilder<?> builder) {
ServletContextInitializerBeans Initializers = new ServletContextInitializerBeans(
this.context);
for (ServletContextInitializer initializer : Initializers) {
if (initializer instanceof FilterRegistrationBean) {
addFilter(builder, (FilterRegistrationBean) initializer);
}
if (initializer instanceof DelegatingFilterProxyRegistrationBean) {
addFilter(builder, (DelegatingFilterProxyRegistrationBean) initializer);
}
}
}
private void addFilter(ConfigurableMockMvcBuilder<?> builder,
FilterRegistrationBean registration) {
addFilter(builder, registration.getFilter(), registration.getUrlPatterns());
}
private void addFilter(ConfigurableMockMvcBuilder<?> builder,
DelegatingFilterProxyRegistrationBean registration) {
addFilter(builder, registration.getFilter(), registration.getUrlPatterns());
}
private void addFilter(ConfigurableMockMvcBuilder<?> builder, Filter filter,
Collection<String> urls) {
if (urls.isEmpty()) {
builder.addFilters(filter);
}
else {
builder.addFilter(filter, urls.toArray(new String[urls.size()]));
}
}
public void setAddFilters(boolean addFilters) {
this.addFilters = addFilters;
}
public boolean isAddFilters() {
return this.addFilters;
}
public void setAlwaysPrint(boolean alwaysPrint) {
this.alwaysPrint = alwaysPrint;
}
public boolean isAlwaysPrint() {
return this.alwaysPrint;
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
import org.springframework.boot.test.context.SpringApplicationTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.BootstrapWith;
import org.springframework.test.web.servlet.MockMvc;
/**
* Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
* for a typical Spring MVC test. Can be used when a test focuses <strong>only</strong> on
* Spring MVC components.
* <p>
* Using this annotation will disable full auto-configuration and instead apply only
* configuration relevant to MVC tests (i.e. {@code @Controller},
* {@code @ControllerAdvice}, {@code @JsonComponent} {@code Filter},
* {@code WebMvcConfigurer} and {@code HandlerMethodArgumentResolver} beans but not
* {@code @Component}, {@code @Service} or {@code @Repository} beans).
* <p>
* By default, tests annotated with {@code @WebMvcTest} will also auto-configure
* {@link MockMvc} (include support for HtmlUnit WebDriver and Selenium WebClient). For
* more fine-grained control of MockMVC that
* {@link AutoConfigureMockMvc @AutoConfigureMockMvc} annotation cab be used.
* <p>
* Typically {@code @WebMvcTest} is used in combination with {@link MockBean @MockBean} or
* {@link Import @Import} to create any collaborators required by your {@code @Controller}
* beans.
* <p>
* If you are looking to load your full application configuration and use MockMVC, you
* should consider {@link SpringApplicationTest @SpringApplicationTest} combined with
* {@link AutoConfigureMockMvc @AutoConfigureMockMvc} rather than this annotation.
*
* @author Phillip Webb
* @see AutoConfigureMockMvc
* @since 1.4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(WebMvcTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(WebMvcTypeExcludeFilter.class)
@ImportWebMvcAutoConfiguration
@AutoConfigureMockMvc
public @interface WebMvcTest {
/**
* Specifies the controllers to test. This is an alias of {@link #controllers()} which
* can be used for brevity if no other attributes are defined. See
* {@link #controllers()} for details.
* @see #controllers()
*/
@AliasFor("controllers")
Class<?>[] value() default {};
/**
* Specifies the controllers to test. May be left blank if all {@code @Controller}
* beans should be added to the application context.
* @see #value()
*/
@AliasFor("value")
Class<?>[] controllers() default {};
/**
* Determines if default filtering should be used with
* {@link SpringBootApplication @SpringBootApplication}. By default only
* {@code @Controller} (when no explicit {@link #controllers() controllers} are
* defined), {@code @ControllerAdvice} and {@code WebMvcConfigurer} beans are
* included.
* @see #includeFilters()
* @see #excludeFilters()
*/
boolean useDefaultFilters() default true;
/**
* A set of include filters which can be used to add otherwise filtered beans to the
* application context.
*/
Filter[] includeFilters() default {};
/**
* A set of exclude filters which can be used to filter beans that would otherwise be
* added to the application context.
*/
Filter[] excludeFilters() default {};
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.test.context.ContextLoader;
import org.springframework.test.context.MergedContextConfiguration;
import org.springframework.test.context.TestContextBootstrapper;
import org.springframework.test.context.web.WebDelegatingSmartContextLoader;
import org.springframework.test.context.web.WebMergedContextConfiguration;
/**
* {@link TestContextBootstrapper} for {@link WebMvcTest @WebMvcTest} support.
*
* @author Phillip Webb
*/
class WebMvcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
@Override
protected Class<? extends ContextLoader> getDefaultContextLoaderClass(
Class<?> testClass) {
return WebDelegatingSmartContextLoader.class;
}
@Override
protected MergedContextConfiguration processMergedContextConfiguration(
MergedContextConfiguration mergedConfig) {
return new WebMergedContextConfiguration(
super.processMergedContextConfiguration(mergedConfig), "");
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.boot.context.embedded.DelegatingFilterProxyRegistrationBean;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* {@link TypeExcludeFilter} for {@link WebMvcTest @WebMvcTest}.
*
* @author Phillip Webb
*/
class WebMvcTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
private static final Set<Class<?>> DEFAULT_INCLUDES;
static {
Set<Class<?>> includes = new LinkedHashSet<Class<?>>();
includes.add(ControllerAdvice.class);
includes.add(JsonComponent.class);
includes.add(WebMvcConfigurer.class);
includes.add(javax.servlet.Filter.class);
includes.add(FilterRegistrationBean.class);
includes.add(DelegatingFilterProxyRegistrationBean.class);
includes.add(HandlerMethodArgumentResolver.class);
DEFAULT_INCLUDES = Collections.unmodifiableSet(includes);
};
private static final Set<Class<?>> DEFAULT_INCLUDES_AND_CONTROLLER;
static {
Set<Class<?>> includes = new LinkedHashSet<Class<?>>(DEFAULT_INCLUDES);
includes.add(Controller.class);
DEFAULT_INCLUDES_AND_CONTROLLER = Collections.unmodifiableSet(includes);
}
private final WebMvcTest annotation;
WebMvcTypeExcludeFilter(Class<?> testClass) {
this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
WebMvcTest.class);
}
@Override
protected boolean defaultInclude(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
if (super.defaultInclude(metadataReader, metadataReaderFactory)) {
return true;
}
for (Class<?> controller : this.annotation.controllers()) {
if (isTypeOrAnnotated(metadataReader, metadataReaderFactory, controller)) {
return true;
}
}
return false;
}
@Override
protected boolean hasAnnotation() {
return this.annotation != null;
}
@Override
protected Filter[] getFilters(FilterType type) {
switch (type) {
case INCLUDE:
return this.annotation.includeFilters();
case EXCLUDE:
return this.annotation.excludeFilters();
}
throw new IllegalStateException("Unsupported type " + type);
}
@Override
protected boolean isUseDefaultFilters() {
return this.annotation.useDefaultFilters();
}
@Override
protected Set<Class<?>> getDefaultIncudes() {
if (ObjectUtils.isEmpty(this.annotation.controllers())) {
return DEFAULT_INCLUDES_AND_CONTROLLER;
}
return DEFAULT_INCLUDES;
}
}
/*
* Copyright 2012-2016 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
*
* http://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.
*/
/**
* Auto-configuration for Spring MVC tests.
*/
package org.springframework.boot.test.autoconfigure.web.servlet;
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
/**
* @author Phillip Webb
*/
public class ExampleArgument {
private final String value;
public ExampleArgument(String value) {
this.value = value;
}
@Override
public String toString() {
return this.value;
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Example {@link Controller} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@RestController
public class ExampleController1 {
@GetMapping("/one")
public String one() {
return "one";
}
@GetMapping("/error")
public String error() {
throw new ExampleException();
}
@GetMapping(path = "/html", produces = "text/html")
public String html() {
return "<html><body>Hello</body></html>";
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Example {@link Controller} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@Controller
public class ExampleController2 {
@GetMapping("/two")
@ResponseBody
public String one(ExampleArgument argument) {
return argument + "two";
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
/**
* Example {@link ControllerAdvice} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@ControllerAdvice
public class ExampleControllerAdvice {
@ExceptionHandler
public ResponseEntity<String> onExampleError(ExampleException exception) {
return ResponseEntity.ok("recovered");
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
/**
* Example exception used in {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
public class ExampleException extends RuntimeException {
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
/**
* Example filter used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@Component
public class ExampleFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
((HttpServletResponse) response).addHeader("x-test", "abc");
}
@Override
public void destroy() {
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.stereotype.Service;
/**
* Example mockable {@link Service} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@Service
public class ExampleMockableService {
public ExampleMockableService() {
throw new IllegalStateException("Should not be called");
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.stereotype.Service;
/**
* Example {@link Service} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@Service
public class ExampleRealService {
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* Example {@link SpringBootApplication} used with {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@SpringBootApplication
public class ExampleWebMvcApplication {
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.util.List;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Example {@link WebMvcConfigurer} used in {@link WebMvcTest} tests.
*
* @author Phillip Webb
*/
@Component
public class ExampleWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(
List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new HandlerMethodArgumentResolver() {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(ExampleArgument.class);
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
return new ExampleArgument("hello");
}
});
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringApplicationTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link SpringApplicationTest} with {@link AutoConfigureMockMvc} (i.e. full
* integration test).
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@SpringApplicationTest
@AutoConfigureMockMvc(alwaysPrint = false)
public class MockMvcSpringApplicationTestIntegrationTests {
@MockBean
private ExampleMockableService service;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private MockMvc mvc;
@Test
public void shouldFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one"))
.andExpect(status().isOk());
}
@Test
public void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo"))
.andExpect(status().isOk());
}
@Test
public void shouldFindControllerAdvice() throws Exception {
this.mvc.perform(get("/error")).andExpect(content().string("recovered"))
.andExpect(status().isOk());
}
@Test
public void shouldHaveRealService() throws Exception {
assertThat(this.applicationContext.getBean(ExampleRealService.class)).isNotNull();
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest} when no explicit controller is defined.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest
public class WebMvcTestAllControllersIntegrationTests {
@Autowired
private MockMvc mvc;
@Test
public void shouldFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one"))
.andExpect(status().isOk());
}
@Test
public void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo"))
.andExpect(status().isOk());
}
@Test
public void shouldFindControllerAdvice() throws Exception {
this.mvc.perform(get("/error")).andExpect(content().string("recovered"))
.andExpect(status().isOk());
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest} when no explicit controller is defined.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest(ExampleController2.class)
public class WebMvcTestOneControllerIntegrationTests {
@Autowired
private MockMvc mvc;
@Test
public void shouldFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(status().isNotFound());
}
@Test
public void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo"))
.andExpect(status().isOk());
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
/**
* Tests for {@link WebMvcTest} servlet filter registration.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest
public class WebMvcTestServletFilterIntegrationTests {
@Autowired
private MockMvc mvc;
@Test
public void shouldApplyFilter() throws Exception {
this.mvc.perform(get("/one")).andExpect(header().string("x-test", "abc"));
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest} with {@link WebClient}.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest
public class WebMvcTestWebClientIntegrationTests {
@Autowired
private WebClient webClient;
@Test
public void shouldAutoConfigureWebClient() throws Exception {
HtmlPage page = this.webClient.getPage("/html");
assertThat(page.getBody().getTextContent()).isEqualTo("Hello");
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest} with {@link WebDriver}.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest
public class WebMvcTestWebDriverIntegrationTests {
@Autowired
private WebDriver webDriver;
@Test
public void shouldAutoConfigureWebClient() throws Exception {
this.webDriver.get("/html");
WebElement element = this.webDriver.findElement(By.tagName("body"));
assertThat(element.getText()).isEqualTo("Hello");
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import com.gargoylesoftware.htmlunit.WebClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
/**
* Tests for {@link WebMvcTest} with {@link AutoConfigureMockMvc}.
*
* @author Phillip Webb
*/
@RunWith(SpringRunner.class)
@WebMvcTest
@AutoConfigureMockMvc(addFilters = false, webClientEnabled = false, webDriverEnabled = false)
public class WebMvcTestWithAutoConfigureMockMvcIntegrationTests {
@Autowired
private ApplicationContext context;
@Autowired
private MockMvc mvc;
@Test
public void shouldNotAddFilters() throws Exception {
this.mvc.perform(get("/one")).andExpect(header().doesNotExist("x-test"));
}
@Test
public void shouldNotHaveWebDriver() throws Exception {
this.context.getBean(WebDriver.class);
}
@Test
public void shouldNotHaveWebClient() throws Exception {
this.context.getBean(WebClient.class);
}
}
/*
* Copyright 2012-2016 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
*
* http://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.boot.test.autoconfigure.web.servlet;
import java.io.IOException;
import org.junit.Test;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTypeExcludeFilter}.
*
* @author Phillip Webb
*/
public class WebMvcTypeExcludeFilterTests {
private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
@Test
public void matchWhenHasNoControllers() throws Exception {
WebMvcTypeExcludeFilter filter = new WebMvcTypeExcludeFilter(
WithNoControllers.class);
assertThat(excludes(filter, Controller1.class)).isFalse();
assertThat(excludes(filter, Controller2.class)).isFalse();
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
assertThat(excludes(filter, ExampleService.class)).isTrue();
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
}
@Test
public void matchWhenHasController() throws Exception {
WebMvcTypeExcludeFilter filter = new WebMvcTypeExcludeFilter(
WithController.class);
assertThat(excludes(filter, Controller1.class)).isFalse();
assertThat(excludes(filter, Controller2.class)).isTrue();
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
assertThat(excludes(filter, ExampleService.class)).isTrue();
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
}
@Test
public void matchNotUsingDefaultFilters() throws Exception {
WebMvcTypeExcludeFilter filter = new WebMvcTypeExcludeFilter(
NotUsingDefaultFilters.class);
assertThat(excludes(filter, Controller1.class)).isTrue();
assertThat(excludes(filter, Controller2.class)).isTrue();
assertThat(excludes(filter, ExampleControllerAdvice.class)).isTrue();
assertThat(excludes(filter, ExampleWeb.class)).isTrue();
assertThat(excludes(filter, ExampleService.class)).isTrue();
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
}
@Test
public void matchWithIncludeFilter() throws Exception {
WebMvcTypeExcludeFilter filter = new WebMvcTypeExcludeFilter(
WithIncludeFilter.class);
assertThat(excludes(filter, Controller1.class)).isFalse();
assertThat(excludes(filter, Controller2.class)).isFalse();
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
assertThat(excludes(filter, ExampleService.class)).isTrue();
assertThat(excludes(filter, ExampleRepository.class)).isFalse();
}
@Test
public void matchWithExcludeFilter() throws Exception {
WebMvcTypeExcludeFilter filter = new WebMvcTypeExcludeFilter(
WithExcludeFilter.class);
assertThat(excludes(filter, Controller1.class)).isTrue();
assertThat(excludes(filter, Controller2.class)).isFalse();
assertThat(excludes(filter, ExampleControllerAdvice.class)).isFalse();
assertThat(excludes(filter, ExampleWeb.class)).isFalse();
assertThat(excludes(filter, ExampleService.class)).isTrue();
assertThat(excludes(filter, ExampleRepository.class)).isTrue();
}
private boolean excludes(WebMvcTypeExcludeFilter filter, Class<?> type)
throws IOException {
MetadataReader metadataReader = this.metadataReaderFactory
.getMetadataReader(type.getName());
return filter.match(metadataReader, this.metadataReaderFactory);
}
@WebMvcTest
static class WithNoControllers {
}
@WebMvcTest(Controller1.class)
static class WithController {
}
@WebMvcTest(useDefaultFilters = false)
static class NotUsingDefaultFilters {
}
@WebMvcTest(includeFilters = @Filter(Repository.class))
static class WithIncludeFilter {
}
@WebMvcTest(excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Controller1.class))
static class WithExcludeFilter {
}
@Controller
static class Controller1 {
}
@Controller
static class Controller2 {
}
@ControllerAdvice
static class ExampleControllerAdvice {
}
static class ExampleWeb extends WebMvcConfigurerAdapter {
}
@Service
static class ExampleService {
}
@Repository
static class ExampleRepository {
}
}
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -235,7 +235,7 @@ abstract class AbstractFilterRegistrationBean extends RegistrationBean { ...@@ -235,7 +235,7 @@ abstract class AbstractFilterRegistrationBean extends RegistrationBean {
* Return the {@link Filter} to be registered. * Return the {@link Filter} to be registered.
* @return the filter * @return the filter
*/ */
protected abstract Filter getFilter(); public abstract Filter getFilter();
/** /**
* Configure registration settings. Subclasses can override this method to perform * Configure registration settings. Subclasses can override this method to perform
......
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -83,7 +83,7 @@ public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistr ...@@ -83,7 +83,7 @@ public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistr
} }
@Override @Override
protected Filter getFilter() { public Filter getFilter() {
return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext()); return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext());
} }
......
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -67,7 +67,7 @@ public class FilterRegistrationBean extends AbstractFilterRegistrationBean { ...@@ -67,7 +67,7 @@ public class FilterRegistrationBean extends AbstractFilterRegistrationBean {
} }
@Override @Override
protected Filter getFilter() { public Filter getFilter() {
return this.filter; return this.filter;
} }
......
...@@ -52,11 +52,11 @@ import org.springframework.util.MultiValueMap; ...@@ -52,11 +52,11 @@ import org.springframework.util.MultiValueMap;
* end. Further sorting is applied within these groups using the * end. Further sorting is applied within these groups using the
* {@link AnnotationAwareOrderComparator}. * {@link AnnotationAwareOrderComparator}.
* *
*
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
* @since 1.4.0
*/ */
class ServletContextInitializerBeans public class ServletContextInitializerBeans
extends AbstractCollection<ServletContextInitializer> { extends AbstractCollection<ServletContextInitializer> {
static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet"; static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
...@@ -73,7 +73,7 @@ class ServletContextInitializerBeans ...@@ -73,7 +73,7 @@ class ServletContextInitializerBeans
private List<ServletContextInitializer> sortedList; private List<ServletContextInitializer> sortedList;
ServletContextInitializerBeans(ListableBeanFactory beanFactory) { public ServletContextInitializerBeans(ListableBeanFactory beanFactory) {
this.initializers = new LinkedMultiValueMap<Class<?>, ServletContextInitializer>(); this.initializers = new LinkedMultiValueMap<Class<?>, ServletContextInitializer>();
addServletContextInitializerBeans(beanFactory); addServletContextInitializerBeans(beanFactory);
addAdaptableBeans(beanFactory); addAdaptableBeans(beanFactory);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment