diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java index 66ccd56872..fab22fb500 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTestContextBootstrapper.java @@ -27,12 +27,14 @@ import org.springframework.test.context.web.WebMergedContextConfiguration; * * @author Phillip Webb * @author Artsiom Yudovin + * @author Lorenzo Dee */ class WebMvcTestContextBootstrapper extends SpringBootTestContextBootstrapper { @Override protected MergedContextConfiguration processMergedContextConfiguration(MergedContextConfiguration mergedConfig) { - return new WebMergedContextConfiguration(super.processMergedContextConfiguration(mergedConfig), ""); + MergedContextConfiguration processedMergedConfiguration = super.processMergedContextConfiguration(mergedConfig); + return new WebMergedContextConfiguration(processedMergedConfiguration, determineResourceBasePath(mergedConfig)); } @Override diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/webapp/inwebapp b/spring-boot-project/spring-boot-test-autoconfigure/src/main/webapp/inwebapp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestServletContextResourceTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestServletContextResourceTests.java new file mode 100644 index 0000000000..390133c2e1 --- /dev/null +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestServletContextResourceTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2019 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.boot.test.autoconfigure.web.servlet.mockmvc; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.servlet.ServletContext; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcTest} when loading resources via {@link ServletContext}. + * + * @author Lorenzo Dee + */ +@RunWith(SpringRunner.class) +@WebMvcTest +public class WebMvcTestServletContextResourceTests { + + @Autowired + private ServletContext servletContext; + + @Test + public void getResourceLocation() throws Exception { + testResource("/inwebapp", "src/main/webapp"); + testResource("/inmetainfresources", "/META-INF/resources"); + testResource("/inresources", "/resources"); + testResource("/instatic", "/static"); + testResource("/inpublic", "/public"); + } + + private void testResource(String path, String expectedLocation) throws MalformedURLException { + URL resource = this.servletContext.getResource(path); + assertThat(resource).isNotNull(); + assertThat(resource.getPath()).contains(expectedLocation); + } + +} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestWithWebAppConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestWithWebAppConfigurationTests.java new file mode 100644 index 0000000000..30705ce99f --- /dev/null +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/web/servlet/mockmvc/WebMvcTestWithWebAppConfigurationTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2019 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.boot.test.autoconfigure.web.servlet.mockmvc; + +import java.net.MalformedURLException; +import java.net.URL; + +import javax.servlet.ServletContext; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcTest @WebMvcTest} when loading resources via the + * {@link ServletContext} with {@link WebAppConfiguration @WebAppConfiguration}. + * + * @author Lorenzo Dee + */ +@RunWith(SpringRunner.class) +@WebMvcTest +@WebAppConfiguration("src/test/webapp") +public class WebMvcTestWithWebAppConfigurationTests { + + @Autowired + private ServletContext servletContext; + + @Test + public void whenBasePathIsCustomizedResourcesCanBeLoadedFromThatLocation() throws Exception { + testResource("/inwebapp", "src/test/webapp"); + testResource("/inmetainfresources", "/META-INF/resources"); + testResource("/inresources", "/resources"); + testResource("/instatic", "/static"); + testResource("/inpublic", "/public"); + } + + private void testResource(String path, String expectedLocation) throws MalformedURLException { + URL resource = this.servletContext.getResource(path); + assertThat(resource).isNotNull(); + assertThat(resource.getPath()).contains(expectedLocation); + } + +} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/META-INF/resources/inmetainfresources b/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/META-INF/resources/inmetainfresources new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/public/inpublic b/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/public/inpublic new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/resources/inresources b/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/resources/inresources new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/static/instatic b/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/static/instatic new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/webapp/inwebapp b/spring-boot-project/spring-boot-test-autoconfigure/src/test/webapp/inwebapp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java index f4fa858985..ce18816778 100644 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java +++ b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java @@ -71,6 +71,7 @@ import org.springframework.util.StringUtils; * @author Andy Wilkinson * @author Brian Clozel * @author Madhura Bhave + * @author Lorenzo Dee * @since 1.4.0 * @see SpringBootTest * @see TestConfiguration @@ -153,11 +154,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr WebApplicationType webApplicationType = getWebApplicationType(mergedConfig); if (webApplicationType == WebApplicationType.SERVLET && (webEnvironment.isEmbedded() || webEnvironment == WebEnvironment.MOCK)) { - WebAppConfiguration webAppConfiguration = AnnotatedElementUtils - .findMergedAnnotation(mergedConfig.getTestClass(), WebAppConfiguration.class); - String resourceBasePath = (webAppConfiguration != null) ? webAppConfiguration.value() - : "src/main/webapp"; - mergedConfig = new WebMergedContextConfiguration(mergedConfig, resourceBasePath); + mergedConfig = new WebMergedContextConfiguration(mergedConfig, determineResourceBasePath(mergedConfig)); } else if (webApplicationType == WebApplicationType.REACTIVE && (webEnvironment.isEmbedded() || webEnvironment == WebEnvironment.MOCK)) { @@ -189,6 +186,20 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr return WebApplicationType.SERVLET; } + /** + * Determines the resource base path for web applications using the value of + * {@link WebAppConfiguration @WebAppConfiguration}, if any, on the test class of the + * given {@code configuration}. Defaults to {@code src/main/webapp} in its absence. + * @param configuration the configure to examine + * @return the resource base path + * @since 2.1.6 + */ + protected String determineResourceBasePath(MergedContextConfiguration configuration) { + WebAppConfiguration webAppConfiguration = AnnotatedElementUtils + .findMergedAnnotation(configuration.getTestClass(), WebAppConfiguration.class); + return (webAppConfiguration != null) ? webAppConfiguration.value() : "src/main/webapp"; + } + private boolean isWebEnvironmentSupported(MergedContextConfiguration mergedConfig) { Class testClass = mergedConfig.getTestClass(); ContextHierarchy hierarchy = AnnotationUtils.getAnnotation(testClass, ContextHierarchy.class);