diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ActuatorConfigurationClassTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ActuatorConfigurationClassTests.java index 8b4fbca695..8c1a5f6f06 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ActuatorConfigurationClassTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/ActuatorConfigurationClassTests.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package org.springframework.boot.actuate; -import org.springframework.boot.test.AbstractConfigurationClassTests; +import org.springframework.boot.test.testutil.AbstractConfigurationClassTests; /** * Tests for the actuator module's {@code @Configuration} classes. diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java index 187acb94f7..2eafa5a520 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java @@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRe import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.ApplicationContextTestUtils; +import org.springframework.boot.test.util.ApplicationContextTestUtils; import org.springframework.context.ConfigurableApplicationContext; /** diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ShutdownParentEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ShutdownParentEndpointTests.java index bc8bef1f08..6963a7e830 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ShutdownParentEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/ShutdownParentEndpointTests.java @@ -24,7 +24,7 @@ import org.junit.Test; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.ApplicationContextTestUtils; +import org.springframework.boot.test.util.ApplicationContextTestUtils; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigureConfigurationClassTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigureConfigurationClassTests.java index a4d27dcade..4065037c24 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigureConfigurationClassTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/AutoConfigureConfigurationClassTests.java @@ -1,5 +1,5 @@ /* - * 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"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package org.springframework.boot.autoconfigure; -import org.springframework.boot.test.AbstractConfigurationClassTests; +import org.springframework.boot.test.testutil.AbstractConfigurationClassTests; /** * Tests for the auto-configure module's {@code @Configuration} classes. diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/BasicErrorControllerDirectMockMvcTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/BasicErrorControllerDirectMockMvcTests.java index 3f58789e14..f1164bf598 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/BasicErrorControllerDirectMockMvcTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/BasicErrorControllerDirectMockMvcTests.java @@ -36,7 +36,7 @@ import org.junit.rules.ExpectedException; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.ApplicationContextTestUtils; +import org.springframework.boot.test.util.ApplicationContextTestUtils; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; diff --git a/spring-boot-test/pom.xml b/spring-boot-test/pom.xml index cff23bbcc8..a7c2ae83cc 100644 --- a/spring-boot-test/pom.xml +++ b/spring-boot-test/pom.xml @@ -30,6 +30,11 @@ javax.servlet-api true + + junit + junit + true + org.apache.httpcomponents httpclient diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/ConfigFileApplicationContextInitializer.java b/spring-boot-test/src/main/java/org/springframework/boot/test/ConfigFileApplicationContextInitializer.java index 395d4bac71..1f7be0a5c7 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/ConfigFileApplicationContextInitializer.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/ConfigFileApplicationContextInitializer.java @@ -18,7 +18,6 @@ package org.springframework.boot.test; import org.springframework.boot.context.config.ConfigFileApplicationListener; import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.test.context.ContextConfiguration; /** @@ -28,19 +27,11 @@ import org.springframework.test.context.ContextConfiguration; * * @author Phillip Webb * @see ConfigFileApplicationListener + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.context.ConfigFileApplicationContextInitializer} */ -public class ConfigFileApplicationContextInitializer - implements ApplicationContextInitializer { - - @Override - public void initialize(final ConfigurableApplicationContext applicationContext) { - new ConfigFileApplicationListener() { - public void apply() { - addPropertySources(applicationContext.getEnvironment(), - applicationContext); - addPostProcessors(applicationContext); - } - }.apply(); - } +@Deprecated +public class ConfigFileApplicationContextInitializer extends + org.springframework.boot.test.context.ConfigFileApplicationContextInitializer { } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/EnvironmentTestUtils.java b/spring-boot-test/src/main/java/org/springframework/boot/test/EnvironmentTestUtils.java index 269e86ff51..a07fede44f 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/EnvironmentTestUtils.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/EnvironmentTestUtils.java @@ -16,22 +16,20 @@ package org.springframework.boot.test; -import java.util.HashMap; -import java.util.Map; - import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; /** * Test utilities for setting environment values. * * @author Dave Syer * @author Stephane Nicoll + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.util.EnvironmentTestUtils} */ +@Deprecated public abstract class EnvironmentTestUtils { /** @@ -43,7 +41,8 @@ public abstract class EnvironmentTestUtils { */ public static void addEnvironment(ConfigurableApplicationContext context, String... pairs) { - addEnvironment(context.getEnvironment(), pairs); + org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment(context, + pairs); } /** @@ -54,7 +53,8 @@ public abstract class EnvironmentTestUtils { */ public static void addEnvironment(ConfigurableEnvironment environment, String... pairs) { - addEnvironment("test", environment, pairs); + org.springframework.boot.test.util.EnvironmentTestUtils + .addEnvironment(environment, pairs); } /** @@ -66,37 +66,8 @@ public abstract class EnvironmentTestUtils { */ public static void addEnvironment(String name, ConfigurableEnvironment environment, String... pairs) { - MutablePropertySources sources = environment.getPropertySources(); - Map map = getOrAdd(sources, name); - for (String pair : pairs) { - int index = getSeparatorIndex(pair); - String key = pair.substring(0, index > 0 ? index : pair.length()); - String value = index > 0 ? pair.substring(index + 1) : ""; - map.put(key.trim(), value.trim()); - } - } - - @SuppressWarnings("unchecked") - private static Map getOrAdd(MutablePropertySources sources, - String name) { - if (sources.contains(name)) { - return (Map) sources.get(name).getSource(); - } - Map map = new HashMap(); - sources.addFirst(new MapPropertySource(name, map)); - return map; - } - - private static int getSeparatorIndex(String pair) { - int colonIndex = pair.indexOf(":"); - int equalIndex = pair.indexOf("="); - if (colonIndex == -1) { - return equalIndex; - } - if (equalIndex == -1) { - return colonIndex; - } - return Math.min(colonIndex, equalIndex); + org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment(name, + environment, pairs); } } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTest.java b/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTest.java index dbd1f9c515..a3785967cf 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTest.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTest.java @@ -23,13 +23,8 @@ 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.env.Environment; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; -import org.springframework.test.context.transaction.TransactionalTestExecutionListener; /** * Test class annotation signifying that the tests are "integration tests" and therefore @@ -41,18 +36,15 @@ import org.springframework.test.context.transaction.TransactionalTestExecutionLi * * @author Dave Syer * @see WebIntegrationTest + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.context.IntegrationTest} */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -// Leave out the ServletTestExecutionListener because it only deals with Mock* servlet -// stuff. A real embedded application will not need the mocks. -@TestExecutionListeners(listeners = { IntegrationTestPropertiesListener.class, - DirtiesContextBeforeModesTestExecutionListener.class, - DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, - TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class }) +@org.springframework.boot.test.context.IntegrationTest +@Deprecated public @interface IntegrationTest { /** @@ -60,6 +52,7 @@ public @interface IntegrationTest { * {@link Environment} before the test runs. * @return the environment properties */ + @AliasFor(annotation = org.springframework.boot.test.context.IntegrationTest.class, attribute = "value") String[] value() default {}; } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTestPropertiesListener.java b/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTestPropertiesListener.java index 0ac0fdf145..9eb7f8c0ec 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTestPropertiesListener.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/IntegrationTestPropertiesListener.java @@ -16,53 +16,16 @@ package org.springframework.boot.test; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.test.context.MergedContextConfiguration; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.support.AbstractTestExecutionListener; -import org.springframework.test.util.ReflectionTestUtils; - /** * Manipulate the TestContext to merge properties from {@code @IntegrationTest}. * * @author Dave Syer * @author Phillip Webb * @since 1.2.0 + * @deprecated since 1.4.0 in favor of IntegrationTestPropertiesListener */ -public class IntegrationTestPropertiesListener extends AbstractTestExecutionListener { - - @Override - public void prepareTestInstance(TestContext testContext) throws Exception { - Class testClass = testContext.getTestClass(); - AnnotationAttributes annotationAttributes = AnnotatedElementUtils - .getMergedAnnotationAttributes(testClass, - IntegrationTest.class.getName()); - if (annotationAttributes != null) { - addPropertySourceProperties(testContext, - annotationAttributes.getStringArray("value")); - } - } - - private void addPropertySourceProperties(TestContext testContext, - String[] properties) { - try { - MergedContextConfiguration configuration = (MergedContextConfiguration) ReflectionTestUtils - .getField(testContext, "mergedContextConfiguration"); - new MergedContextConfigurationProperties(configuration).add(properties); - } - catch (RuntimeException ex) { - throw ex; - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } +@Deprecated +public class IntegrationTestPropertiesListener + extends org.springframework.boot.test.context.IntegrationTestPropertiesListener { } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/OutputCapture.java b/spring-boot-test/src/main/java/org/springframework/boot/test/OutputCapture.java index 0676892efe..608f193254 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/OutputCapture.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/OutputCapture.java @@ -16,181 +16,14 @@ package org.springframework.boot.test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; - -import org.hamcrest.Matcher; -import org.junit.Assert; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import org.springframework.boot.ansi.AnsiOutput; -import org.springframework.boot.ansi.AnsiOutput.Enabled; - -import static org.hamcrest.Matchers.allOf; - /** * JUnit {@code @Rule} to capture output from System.out and System.err. * * @author Phillip Webb * @author Andy Wilkinson + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.rule.OutputCapture} */ -public class OutputCapture implements TestRule { - - private CaptureOutputStream captureOut; - - private CaptureOutputStream captureErr; - - private ByteArrayOutputStream copy; - - private List> matchers = new ArrayList>(); - - @Override - public Statement apply(final Statement base, Description description) { - return new Statement() { - @Override - public void evaluate() throws Throwable { - captureOutput(); - try { - base.evaluate(); - } - finally { - try { - if (!OutputCapture.this.matchers.isEmpty()) { - String output = OutputCapture.this.toString(); - Assert.assertThat(output, allOf(OutputCapture.this.matchers)); - } - } - finally { - releaseOutput(); - } - } - } - }; - } - - protected void captureOutput() { - AnsiOutputControl.get().disableAnsiOutput(); - this.copy = new ByteArrayOutputStream(); - this.captureOut = new CaptureOutputStream(System.out, this.copy); - this.captureErr = new CaptureOutputStream(System.err, this.copy); - System.setOut(new PrintStream(this.captureOut)); - System.setErr(new PrintStream(this.captureErr)); - } - - protected void releaseOutput() { - AnsiOutputControl.get().enabledAnsiOutput(); - System.setOut(this.captureOut.getOriginal()); - System.setErr(this.captureErr.getOriginal()); - this.copy = null; - } - - public void flush() { - try { - this.captureOut.flush(); - this.captureErr.flush(); - } - catch (IOException ex) { - // ignore - } - } - - @Override - public String toString() { - flush(); - return this.copy.toString(); - } - - /** - * Verify that the output is matched by the supplied {@code matcher}. Verification is - * performed after the test method has executed. - * @param matcher the matcher - */ - public void expect(Matcher matcher) { - this.matchers.add(matcher); - } - - private static class CaptureOutputStream extends OutputStream { - - private final PrintStream original; - - private final OutputStream copy; - - CaptureOutputStream(PrintStream original, OutputStream copy) { - this.original = original; - this.copy = copy; - } - - @Override - public void write(int b) throws IOException { - this.copy.write(b); - this.original.write(b); - this.original.flush(); - } - - @Override - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - this.copy.write(b, off, len); - this.original.write(b, off, len); - } - - public PrintStream getOriginal() { - return this.original; - } - - @Override - public void flush() throws IOException { - this.copy.flush(); - this.original.flush(); - } - - } - - /** - * Allow AnsiOutput to not be on the test classpath. - */ - private static class AnsiOutputControl { - - public void disableAnsiOutput() { - } - - public void enabledAnsiOutput() { - } - - public static AnsiOutputControl get() { - try { - Class.forName("org.springframework.boot.ansi.AnsiOutput"); - return new AnsiPresentOutputControl(); - } - catch (ClassNotFoundException ex) { - return new AnsiOutputControl(); - } - } - - } - - private static class AnsiPresentOutputControl extends AnsiOutputControl { - - @Override - public void disableAnsiOutput() { - AnsiOutput.setEnabled(Enabled.NEVER); - } - - @Override - public void enabledAnsiOutput() { - AnsiOutput.setEnabled(Enabled.DETECT); - } - - } - +@Deprecated +public class OutputCapture extends org.springframework.boot.test.rule.OutputCapture { } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationConfiguration.java b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationConfiguration.java index ff29565ada..e4566933d7 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationConfiguration.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationConfiguration.java @@ -39,12 +39,15 @@ import org.springframework.test.context.ContextConfiguration; * @author Sam Brannen * @see SpringApplicationContextLoader * @see ContextConfiguration + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.context.SpringApplicationConfiguration} */ -@ContextConfiguration(loader = SpringApplicationContextLoader.class) @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@org.springframework.boot.test.context.SpringApplicationConfiguration +@Deprecated public @interface SpringApplicationConfiguration { /** @@ -52,7 +55,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#classes() * @return the context configuration classes */ - @AliasFor("classes") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "value") Class[] value() default {}; /** @@ -60,7 +63,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#locations() * @return the context configuration locations */ - @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "locations") String[] locations() default {}; /** @@ -68,7 +71,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#classes() * @return the context configuration classes */ - @AliasFor("value") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "classes") Class[] classes() default {}; /** @@ -76,7 +79,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#initializers() * @return the context configuration initializers */ - @AliasFor(annotation = ContextConfiguration.class, attribute = "initializers") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "initializers") Class>[] initializers() default {}; /** @@ -84,7 +87,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#inheritLocations() * @return {@code true} if context locations should be inherited */ - @AliasFor(annotation = ContextConfiguration.class, attribute = "inheritLocations") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "inheritLocations") boolean inheritLocations() default true; /** @@ -92,7 +95,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#inheritInitializers() * @return {@code true} if context initializers should be inherited */ - @AliasFor(annotation = ContextConfiguration.class, attribute = "inheritInitializers") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "inheritInitializers") boolean inheritInitializers() default true; /** @@ -100,7 +103,7 @@ public @interface SpringApplicationConfiguration { * @see ContextConfiguration#name() * @return the name of the context hierarchy level */ - @AliasFor(annotation = ContextConfiguration.class, attribute = "name") + @AliasFor(annotation = org.springframework.boot.test.context.SpringApplicationConfiguration.class, attribute = "name") String name() default ""; } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationContextLoader.java index 70234b9f29..c22d9af9ac 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationContextLoader.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringApplicationContextLoader.java @@ -16,40 +16,9 @@ package org.springframework.boot.test; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.BeanUtils; import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.web.ServletContextApplicationContextInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.SpringVersion; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.StandardEnvironment; import org.springframework.mock.web.MockServletContext; -import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextLoader; -import org.springframework.test.context.MergedContextConfiguration; -import org.springframework.test.context.support.AbstractContextLoader; -import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils; -import org.springframework.test.context.support.TestPropertySourceUtils; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.context.web.WebMergedContextConfiguration; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.context.support.GenericWebApplicationContext; /** * A {@link ContextLoader} that can be used to test Spring Boot applications (those that @@ -69,218 +38,11 @@ import org.springframework.web.context.support.GenericWebApplicationContext; * @see IntegrationTest * @see WebIntegrationTest * @see TestRestTemplate + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.context.SpringApplicationContextLoader} */ -public class SpringApplicationContextLoader extends AbstractContextLoader { - - @Override - public ApplicationContext loadContext(final MergedContextConfiguration config) - throws Exception { - assertValidAnnotations(config.getTestClass()); - SpringApplication application = getSpringApplication(); - application.setMainApplicationClass(config.getTestClass()); - application.setSources(getSources(config)); - ConfigurableEnvironment environment = new StandardEnvironment(); - if (!ObjectUtils.isEmpty(config.getActiveProfiles())) { - setActiveProfiles(environment, config.getActiveProfiles()); - } - Map properties = getEnvironmentProperties(config); - addProperties(environment, properties); - application.setEnvironment(environment); - List> initializers = getInitializers(config, - application); - if (config instanceof WebMergedContextConfiguration) { - new WebConfigurer().configure(config, application, initializers); - } - else { - application.setWebEnvironment(false); - } - application.setInitializers(initializers); - ConfigurableApplicationContext applicationContext = application.run(); - return applicationContext; - } - - private void assertValidAnnotations(Class testClass) { - boolean hasWebAppConfiguration = AnnotationUtils.findAnnotation(testClass, - WebAppConfiguration.class) != null; - boolean hasWebIntegrationTest = AnnotationUtils.findAnnotation(testClass, - WebIntegrationTest.class) != null; - if (hasWebAppConfiguration && hasWebIntegrationTest) { - throw new IllegalStateException("@WebIntegrationTest and " - + "@WebAppConfiguration cannot be used together"); - } - } - - /** - * Builds new {@link org.springframework.boot.SpringApplication} instance. You can - * override this method to add custom behavior - * @return {@link org.springframework.boot.SpringApplication} instance - */ - protected SpringApplication getSpringApplication() { - return new SpringApplication(); - } - - private Set getSources(MergedContextConfiguration mergedConfig) { - Set sources = new LinkedHashSet(); - sources.addAll(Arrays.asList(mergedConfig.getClasses())); - sources.addAll(Arrays.asList(mergedConfig.getLocations())); - Assert.state(!sources.isEmpty(), "No configuration classes " - + "or locations found in @SpringApplicationConfiguration. " - + "For default configuration detection to work you need " - + "Spring 4.0.3 or better (found " + SpringVersion.getVersion() + ")."); - return sources; - } - - private void setActiveProfiles(ConfigurableEnvironment environment, - String[] profiles) { - EnvironmentTestUtils.addEnvironment(environment, "spring.profiles.active=" - + StringUtils.arrayToCommaDelimitedString(profiles)); - } - - protected Map getEnvironmentProperties( - MergedContextConfiguration config) { - Map properties = new LinkedHashMap(); - // JMX bean names will clash if the same bean is used in multiple contexts - disableJmx(properties); - properties.putAll(TestPropertySourceUtils - .convertInlinedPropertiesToMap(config.getPropertySourceProperties())); - if (!TestAnnotations.isIntegrationTest(config)) { - properties.putAll(getDefaultEnvironmentProperties()); - } - return properties; - } - - private void disableJmx(Map properties) { - properties.put("spring.jmx.enabled", "false"); - } - - private Map getDefaultEnvironmentProperties() { - return Collections.singletonMap("server.port", "-1"); - } - - private void addProperties(ConfigurableEnvironment environment, - Map properties) { - // @IntegrationTest properties go before external configuration and after system - environment.getPropertySources().addAfter( - StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, - new MapPropertySource("integrationTest", properties)); - } - - private List> getInitializers( - MergedContextConfiguration mergedConfig, SpringApplication application) { - List> initializers = new ArrayList>(); - initializers.add(new PropertySourceLocationsInitializer( - mergedConfig.getPropertySourceLocations())); - initializers.addAll(application.getInitializers()); - for (Class> initializerClass : mergedConfig - .getContextInitializerClasses()) { - initializers.add(BeanUtils.instantiate(initializerClass)); - } - return initializers; - } - - @Override - public void processContextConfiguration( - ContextConfigurationAttributes configAttributes) { - super.processContextConfiguration(configAttributes); - if (!configAttributes.hasResources()) { - Class[] defaultConfigClasses = detectDefaultConfigurationClasses( - configAttributes.getDeclaringClass()); - configAttributes.setClasses(defaultConfigClasses); - } - } - - /** - * Detect the default configuration classes for the supplied test class. By default - * simply delegates to - * {@link AnnotationConfigContextLoaderUtils#detectDefaultConfigurationClasses} . - * @param declaringClass the test class that declared {@code @ContextConfiguration} - * @return an array of default configuration classes, potentially empty but never - * {@code null} - * @see AnnotationConfigContextLoaderUtils - */ - protected Class[] detectDefaultConfigurationClasses(Class declaringClass) { - return AnnotationConfigContextLoaderUtils - .detectDefaultConfigurationClasses(declaringClass); - } - - @Override - public ApplicationContext loadContext(String... locations) throws Exception { - throw new UnsupportedOperationException("SpringApplicationContextLoader " - + "does not support the loadContext(String...) method"); - } - - @Override - protected String[] getResourceSuffixes() { - return new String[] { "-context.xml", "Context.groovy" }; - } - - @Override - protected String getResourceSuffix() { - throw new IllegalStateException(); - } - - /** - * Inner class to configure {@link WebMergedContextConfiguration}. - */ - private static class WebConfigurer { - - private static final Class WEB_CONTEXT_CLASS = GenericWebApplicationContext.class; - - void configure(MergedContextConfiguration configuration, - SpringApplication application, - List> initializers) { - if (!TestAnnotations.isIntegrationTest(configuration)) { - WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; - addMockServletContext(initializers, webConfiguration); - application.setApplicationContextClass(WEB_CONTEXT_CLASS); - } - } - - private void addMockServletContext( - List> initializers, - WebMergedContextConfiguration webConfiguration) { - SpringBootMockServletContext servletContext = new SpringBootMockServletContext( - webConfiguration.getResourceBasePath()); - initializers.add(0, - new ServletContextApplicationContextInitializer(servletContext)); - } - - } - - /** - * {@link ApplicationContextInitializer} to setup test property source locations. - */ - private static class PropertySourceLocationsInitializer - implements ApplicationContextInitializer { - - private final String[] propertySourceLocations; - - PropertySourceLocationsInitializer(String[] propertySourceLocations) { - this.propertySourceLocations = propertySourceLocations; - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - TestPropertySourceUtils.addPropertiesFilesToEnvironment(applicationContext, - this.propertySourceLocations); - } - - } - - private static class TestAnnotations { - - public static boolean isIntegrationTest( - MergedContextConfiguration configuration) { - return (hasAnnotation(configuration, IntegrationTest.class) - || hasAnnotation(configuration, WebIntegrationTest.class)); - } - - private static boolean hasAnnotation(MergedContextConfiguration configuration, - Class annotation) { - return (AnnotationUtils.findAnnotation(configuration.getTestClass(), - annotation) != null); - } - - } +@Deprecated +public class SpringApplicationContextLoader + extends org.springframework.boot.test.context.SpringApplicationContextLoader { } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringBootMockServletContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringBootMockServletContext.java index 3d79f4bb0e..57d23dc746 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/SpringBootMockServletContext.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/SpringBootMockServletContext.java @@ -16,13 +16,6 @@ package org.springframework.boot.test; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; - -import org.springframework.core.io.FileSystemResourceLoader; -import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.mock.web.MockServletContext; @@ -32,81 +25,20 @@ import org.springframework.mock.web.MockServletContext; * found. * * @author Phillip Webb + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.mock.web.SpringBootMockServletContext} */ -public class SpringBootMockServletContext extends MockServletContext { - - private static final String[] SPRING_BOOT_RESOURCE_LOCATIONS = new String[] { - "classpath:META-INF/resources", "classpath:resources", "classpath:static", - "classpath:public" }; - - private final ResourceLoader resourceLoader; - - private File emptyRootFolder; +@Deprecated +public class SpringBootMockServletContext + extends org.springframework.boot.test.mock.web.SpringBootMockServletContext { public SpringBootMockServletContext(String resourceBasePath) { - this(resourceBasePath, new FileSystemResourceLoader()); + super(resourceBasePath); } public SpringBootMockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { super(resourceBasePath, resourceLoader); - this.resourceLoader = resourceLoader; - } - - @Override - protected String getResourceLocation(String path) { - if (!path.startsWith("/")) { - path = "/" + path; - } - String resourceLocation = getResourceBasePathLocation(path); - if (exists(resourceLocation)) { - return resourceLocation; - } - for (String prefix : SPRING_BOOT_RESOURCE_LOCATIONS) { - resourceLocation = prefix + path; - if (exists(resourceLocation)) { - return resourceLocation; - } - } - return super.getResourceLocation(path); } - protected final String getResourceBasePathLocation(String path) { - return super.getResourceLocation(path); - } - - private boolean exists(String resourceLocation) { - try { - Resource resource = this.resourceLoader.getResource(resourceLocation); - return resource.exists(); - } - catch (Exception ex) { - return false; - } - } - - @Override - public URL getResource(String path) throws MalformedURLException { - URL resource = super.getResource(path); - if (resource == null && "/".equals(path)) { - // Liquibase assumes that "/" always exists, if we don't have a directory - // use a temporary location. - try { - if (this.emptyRootFolder == null) { - synchronized (this) { - File tempFolder = File.createTempFile("spr", "servlet"); - tempFolder.delete(); - tempFolder.mkdirs(); - tempFolder.deleteOnExit(); - this.emptyRootFolder = tempFolder; - } - } - return this.emptyRootFolder.toURI().toURL(); - } - catch (IOException ex) { - // Ignore - } - } - return resource; - } } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/TestRestTemplate.java b/spring-boot-test/src/main/java/org/springframework/boot/test/TestRestTemplate.java index c262ab7925..4618c69704 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/TestRestTemplate.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/TestRestTemplate.java @@ -16,31 +16,6 @@ package org.springframework.boot.test; -import java.io.IOException; -import java.net.URI; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.config.RequestConfig.Builder; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.protocol.HttpContext; - -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.util.Base64Utils; -import org.springframework.util.ClassUtils; -import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.RestTemplate; /** @@ -51,17 +26,19 @@ import org.springframework.web.client.RestTemplate; * * @author Dave Syer * @author Phillip Webb + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.web.client.TestRestTemplate} */ -public class TestRestTemplate extends RestTemplate { - - private static final Charset UTF_8 = Charset.forName("UTF-8"); +@Deprecated +public class TestRestTemplate + extends org.springframework.boot.test.web.client.TestRestTemplate { /** * Create a new {@link TestRestTemplate} instance. * @param httpClientOptions client options to use if the Apache HTTP Client is used */ public TestRestTemplate(HttpClientOption... httpClientOptions) { - this(null, null, httpClientOptions); + super(httpClientOptions); } /** @@ -72,103 +49,7 @@ public class TestRestTemplate extends RestTemplate { */ public TestRestTemplate(String username, String password, HttpClientOption... httpClientOptions) { - if (ClassUtils.isPresent("org.apache.http.client.config.RequestConfig", null)) { - setRequestFactory( - new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions)); - } - addAuthentication(username, password); - setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - - } - - private void addAuthentication(String username, String password) { - if (username == null) { - return; - } - List interceptors = Collections - .singletonList( - new BasicAuthorizationInterceptor(username, password)); - setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(), - interceptors)); - } - - /** - * Options used to customize the Apache Http Client if it is used. - */ - public enum HttpClientOption { - - /** - * Enable cookies. - */ - ENABLE_COOKIES, - - /** - * Enable redirects. - */ - ENABLE_REDIRECTS - - } - - private static class BasicAuthorizationInterceptor - implements ClientHttpRequestInterceptor { - - private final String username; - - private final String password; - - BasicAuthorizationInterceptor(String username, String password) { - this.username = username; - this.password = (password == null ? "" : password); - } - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - String token = Base64Utils.encodeToString( - (this.username + ":" + this.password).getBytes(UTF_8)); - request.getHeaders().add("Authorization", "Basic " + token); - return execution.execute(request, body); - } - - } - - /** - * {@link HttpComponentsClientHttpRequestFactory} to apply customizations. - */ - protected static class CustomHttpComponentsClientHttpRequestFactory - extends HttpComponentsClientHttpRequestFactory { - - private final String cookieSpec; - - private final boolean enableRedirects; - - public CustomHttpComponentsClientHttpRequestFactory( - HttpClientOption[] httpClientOptions) { - Set options = new HashSet( - Arrays.asList(httpClientOptions)); - this.cookieSpec = (options.contains(HttpClientOption.ENABLE_COOKIES) - ? CookieSpecs.STANDARD : CookieSpecs.IGNORE_COOKIES); - this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS); - } - - @Override - protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { - HttpClientContext context = HttpClientContext.create(); - context.setRequestConfig(getRequestConfig()); - return context; - } - - protected RequestConfig getRequestConfig() { - Builder builder = RequestConfig.custom().setCookieSpec(this.cookieSpec) - .setAuthenticationEnabled(false) - .setRedirectsEnabled(this.enableRedirects); - return builder.build(); - } - + super(username, password, httpClientOptions); } } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/WebIntegrationTest.java b/spring-boot-test/src/main/java/org/springframework/boot/test/WebIntegrationTest.java index 8894e06403..6fae84ba2c 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/WebIntegrationTest.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/WebIntegrationTest.java @@ -24,8 +24,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.boot.context.web.LocalServerPort; +import org.springframework.core.annotation.AliasFor; import org.springframework.core.env.Environment; -import org.springframework.test.context.BootstrapWith; /** * Test class annotation signifying that the tests are "web integration tests" and @@ -39,12 +39,15 @@ import org.springframework.test.context.BootstrapWith; * @author Phillip Webb * @since 1.2.1 * @see IntegrationTest + * @deprecated since 1.4.0 in favor of + * {@link org.springframework.boot.test.context.web.WebIntegrationTest} */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -@BootstrapWith(WebAppIntegrationTestContextBootstrapper.class) +@org.springframework.boot.test.context.web.WebIntegrationTest +@Deprecated public @interface WebIntegrationTest { /** @@ -52,6 +55,7 @@ public @interface WebIntegrationTest { * {@link Environment} before the test runs. * @return properties to add to the context */ + @AliasFor(annotation = org.springframework.boot.test.context.web.WebIntegrationTest.class, attribute = "value") String[] value() default {}; /** @@ -61,6 +65,7 @@ public @interface WebIntegrationTest { * test. * @return if a random port should be used */ + @AliasFor(annotation = org.springframework.boot.test.context.web.WebIntegrationTest.class, attribute = "randomPort") boolean randomPort() default false; } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializer.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializer.java new file mode 100644 index 0000000000..12d86b633e --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializer.java @@ -0,0 +1,47 @@ +/* + * 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.context; + +import org.springframework.boot.context.config.ConfigFileApplicationListener; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.ContextConfiguration; + +/** + * {@link ApplicationContextInitializer} that can be used with the + * {@link ContextConfiguration#initializers()} to trigger loading of + * {@literal application.properties}. + * + * @author Phillip Webb + * @since 1.4.0 + * @see ConfigFileApplicationListener + */ +public class ConfigFileApplicationContextInitializer + implements ApplicationContextInitializer { + + @Override + public void initialize(final ConfigurableApplicationContext applicationContext) { + new ConfigFileApplicationListener() { + public void apply() { + addPropertySources(applicationContext.getEnvironment(), + applicationContext); + addPostProcessors(applicationContext); + } + }.apply(); + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTest.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTest.java new file mode 100644 index 0000000000..bed0ab54f9 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTest.java @@ -0,0 +1,65 @@ +/* + * 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.context; + +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.core.env.Environment; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; +import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextTestExecutionListener; +import org.springframework.test.context.transaction.TransactionalTestExecutionListener; + +/** + * Test class annotation signifying that the tests are "integration tests" and therefore + * require full startup in the same way as a production application. Normally used in + * conjunction with {@code @SpringApplicationConfiguration}. + *

+ * If your test also uses {@code @WebAppConfiguration} consider using the + * {@link org.springframework.boot.test.context.web.WebIntegrationTest} instead. + * + * @author Dave Syer + * @see org.springframework.boot.test.context.web.WebIntegrationTest + */ +@Documented +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +// Leave out the ServletTestExecutionListener because it only deals with Mock* servlet +// stuff. A real embedded application will not need the mocks. +@TestExecutionListeners(listeners = { IntegrationTestPropertiesListener.class, + DirtiesContextBeforeModesTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, + TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class }) +public @interface IntegrationTest { + + /** + * Properties in form {@literal key=value} that should be added to the Spring + * {@link Environment} before the test runs. + * @return the environment properties + */ + String[] value() default {}; + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTestPropertiesListener.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTestPropertiesListener.java new file mode 100644 index 0000000000..a405ed57f6 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/IntegrationTestPropertiesListener.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-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.context; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.test.context.TestContext; +import org.springframework.test.context.support.AbstractTestExecutionListener; +import org.springframework.test.util.ReflectionTestUtils; + +/** + * Manipulate the TestContext to merge properties from {@code @IntegrationTest}. + * + * @author Dave Syer + * @author Phillip Webb + * @since 1.4.0 + */ +public class IntegrationTestPropertiesListener extends AbstractTestExecutionListener { + + @Override + public void prepareTestInstance(TestContext testContext) throws Exception { + Class testClass = testContext.getTestClass(); + AnnotationAttributes annotationAttributes = AnnotatedElementUtils + .getMergedAnnotationAttributes(testClass, + IntegrationTest.class.getName()); + if (annotationAttributes != null) { + addPropertySourceProperties(testContext, + annotationAttributes.getStringArray("value")); + } + } + + private void addPropertySourceProperties(TestContext testContext, + String[] properties) { + try { + MergedContextConfiguration configuration = (MergedContextConfiguration) ReflectionTestUtils + .getField(testContext, "mergedContextConfiguration"); + new MergedContextConfigurationProperties(configuration).add(properties); + } + catch (RuntimeException ex) { + throw ex; + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/MergedContextConfigurationProperties.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/MergedContextConfigurationProperties.java similarity index 84% rename from spring-boot-test/src/main/java/org/springframework/boot/test/MergedContextConfigurationProperties.java rename to spring-boot-test/src/main/java/org/springframework/boot/test/context/MergedContextConfigurationProperties.java index 8898e7b173..c55338c21c 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/MergedContextConfigurationProperties.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/MergedContextConfigurationProperties.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.context; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; +import org.springframework.boot.test.context.web.WebIntegrationTest; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.util.ReflectionTestUtils; @@ -27,13 +28,14 @@ import org.springframework.test.util.ReflectionTestUtils; * Provides access to {@link MergedContextConfiguration} properties. * * @author Phillip Webb - * @since 1.2.1 + * @since 1.4.0 */ -class MergedContextConfigurationProperties { +public class MergedContextConfigurationProperties { private final MergedContextConfiguration configuration; - MergedContextConfigurationProperties(MergedContextConfiguration configuration) { + public MergedContextConfigurationProperties( + MergedContextConfiguration configuration) { this.configuration = configuration; } @@ -55,7 +57,7 @@ class MergedContextConfigurationProperties { * @param propertySourceProperties the property source properties */ private void addIntegrationTestProperty(Set propertySourceProperties) { - propertySourceProperties.add(IntegrationTest.class.getName() + "=true"); + propertySourceProperties.add(WebIntegrationTest.class.getName() + "=true"); } } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationConfiguration.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationConfiguration.java new file mode 100644 index 0000000000..95ea77bba1 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationConfiguration.java @@ -0,0 +1,106 @@ +/* + * 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.context; + +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.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.annotation.AliasFor; +import org.springframework.test.context.ContextConfiguration; + +/** + * Class-level annotation that is used to determine how to load and configure an + * {@code ApplicationContext} for integration tests. + *

+ * Similar to the standard {@link ContextConfiguration @ContextConfiguration} but uses + * Spring Boot's {@link SpringApplicationContextLoader}. + * + * @author Dave Syer + * @author Sam Brannen + * @see SpringApplicationContextLoader + * @see ContextConfiguration + */ +@ContextConfiguration(loader = SpringApplicationContextLoader.class) +@Documented +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SpringApplicationConfiguration { + + /** + * The context configuration classes. + * @see ContextConfiguration#classes() + * @return the context configuration classes + */ + @AliasFor("classes") + Class[] value() default {}; + + /** + * The context configuration locations. + * @see ContextConfiguration#locations() + * @return the context configuration locations + */ + @AliasFor(annotation = ContextConfiguration.class, attribute = "locations") + String[] locations() default {}; + + /** + * The context configuration classes. + * @see ContextConfiguration#classes() + * @return the context configuration classes + */ + @AliasFor("value") + Class[] classes() default {}; + + /** + * The context configuration initializers. + * @see ContextConfiguration#initializers() + * @return the context configuration initializers + */ + @AliasFor(annotation = ContextConfiguration.class, attribute = "initializers") + Class>[] initializers() default {}; + + /** + * Should context locations be inherited. + * @see ContextConfiguration#inheritLocations() + * @return {@code true} if context locations should be inherited + */ + @AliasFor(annotation = ContextConfiguration.class, attribute = "inheritLocations") + boolean inheritLocations() default true; + + /** + * Should initializers be inherited. + * @see ContextConfiguration#inheritInitializers() + * @return {@code true} if context initializers should be inherited + */ + @AliasFor(annotation = ContextConfiguration.class, attribute = "inheritInitializers") + boolean inheritInitializers() default true; + + /** + * The name of the context hierarchy level. + * @see ContextConfiguration#name() + * @return the name of the context hierarchy level + */ + @AliasFor(annotation = ContextConfiguration.class, attribute = "name") + String name() default ""; + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationContextLoader.java new file mode 100644 index 0000000000..6a5afb0d69 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringApplicationContextLoader.java @@ -0,0 +1,288 @@ +/* + * 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.context; + +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.BeanUtils; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.context.web.ServletContextApplicationContextInitializer; +import org.springframework.boot.test.context.web.WebIntegrationTest; +import org.springframework.boot.test.mock.web.SpringBootMockServletContext; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.SpringVersion; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.context.ContextConfigurationAttributes; +import org.springframework.test.context.ContextLoader; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.test.context.support.AbstractContextLoader; +import org.springframework.test.context.support.AnnotationConfigContextLoaderUtils; +import org.springframework.test.context.support.TestPropertySourceUtils; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.context.web.WebMergedContextConfiguration; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.context.support.GenericWebApplicationContext; + +/** + * A {@link ContextLoader} that can be used to test Spring Boot applications (those that + * normally startup using {@link SpringApplication}). Can be used to test non-web features + * (like a repository layer) or start an fully-configured embedded servlet container. + *

+ * Use {@code @WebIntegrationTest} (or {@code @IntegrationTest} with + * {@code @WebAppConfiguration}) to indicate that you want to use a real servlet container + * or {@code @WebAppConfiguration} alone to use a {@link MockServletContext}. + *

+ * If {@code @ActiveProfiles} are provided in the test class they will be used to create + * the application context. + * + * @author Dave Syer + * @author Phillip Webb + * @author Andy Wilkinson + * @see IntegrationTest + * @see WebIntegrationTest + * @see TestRestTemplate + */ +public class SpringApplicationContextLoader extends AbstractContextLoader { + + @Override + public ApplicationContext loadContext(final MergedContextConfiguration config) + throws Exception { + assertValidAnnotations(config.getTestClass()); + SpringApplication application = getSpringApplication(); + application.setMainApplicationClass(config.getTestClass()); + application.setSources(getSources(config)); + ConfigurableEnvironment environment = new StandardEnvironment(); + if (!ObjectUtils.isEmpty(config.getActiveProfiles())) { + setActiveProfiles(environment, config.getActiveProfiles()); + } + Map properties = getEnvironmentProperties(config); + addProperties(environment, properties); + application.setEnvironment(environment); + List> initializers = getInitializers(config, + application); + if (config instanceof WebMergedContextConfiguration) { + new WebConfigurer().configure(config, application, initializers); + } + else { + application.setWebEnvironment(false); + } + application.setInitializers(initializers); + ConfigurableApplicationContext applicationContext = application.run(); + return applicationContext; + } + + private void assertValidAnnotations(Class testClass) { + if (AnnotatedElementUtils.isAnnotated(testClass, WebAppConfiguration.class) + && AnnotatedElementUtils.isAnnotated(testClass, + WebIntegrationTest.class)) { + throw new IllegalStateException("@WebIntegrationTest and " + + "@WebAppConfiguration cannot be used together"); + } + } + + /** + * Builds new {@link org.springframework.boot.SpringApplication} instance. You can + * override this method to add custom behavior + * @return {@link org.springframework.boot.SpringApplication} instance + */ + protected SpringApplication getSpringApplication() { + return new SpringApplication(); + } + + private Set getSources(MergedContextConfiguration mergedConfig) { + Set sources = new LinkedHashSet(); + sources.addAll(Arrays.asList(mergedConfig.getClasses())); + sources.addAll(Arrays.asList(mergedConfig.getLocations())); + Assert.state(!sources.isEmpty(), "No configuration classes " + + "or locations found in @SpringApplicationConfiguration. " + + "For default configuration detection to work you need " + + "Spring 4.0.3 or better (found " + SpringVersion.getVersion() + ")."); + return sources; + } + + private void setActiveProfiles(ConfigurableEnvironment environment, + String[] profiles) { + EnvironmentTestUtils.addEnvironment(environment, "spring.profiles.active=" + + StringUtils.arrayToCommaDelimitedString(profiles)); + } + + protected Map getEnvironmentProperties( + MergedContextConfiguration config) { + Map properties = new LinkedHashMap(); + // JMX bean names will clash if the same bean is used in multiple contexts + disableJmx(properties); + properties.putAll(TestPropertySourceUtils + .convertInlinedPropertiesToMap(config.getPropertySourceProperties())); + if (!TestAnnotations.isIntegrationTest(config)) { + properties.putAll(getDefaultEnvironmentProperties()); + } + return properties; + } + + private void disableJmx(Map properties) { + properties.put("spring.jmx.enabled", "false"); + } + + private Map getDefaultEnvironmentProperties() { + return Collections.singletonMap("server.port", "-1"); + } + + private void addProperties(ConfigurableEnvironment environment, + Map properties) { + // @IntegrationTest properties go before external configuration and after system + environment.getPropertySources().addAfter( + StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, + new MapPropertySource("integrationTest", properties)); + } + + private List> getInitializers( + MergedContextConfiguration mergedConfig, SpringApplication application) { + List> initializers = new ArrayList>(); + initializers.add(new PropertySourceLocationsInitializer( + mergedConfig.getPropertySourceLocations())); + initializers.addAll(application.getInitializers()); + for (Class> initializerClass : mergedConfig + .getContextInitializerClasses()) { + initializers.add(BeanUtils.instantiate(initializerClass)); + } + return initializers; + } + + @Override + public void processContextConfiguration( + ContextConfigurationAttributes configAttributes) { + super.processContextConfiguration(configAttributes); + if (!configAttributes.hasResources()) { + Class[] defaultConfigClasses = detectDefaultConfigurationClasses( + configAttributes.getDeclaringClass()); + configAttributes.setClasses(defaultConfigClasses); + } + } + + /** + * Detect the default configuration classes for the supplied test class. By default + * simply delegates to + * {@link AnnotationConfigContextLoaderUtils#detectDefaultConfigurationClasses} . + * @param declaringClass the test class that declared {@code @ContextConfiguration} + * @return an array of default configuration classes, potentially empty but never + * {@code null} + * @see AnnotationConfigContextLoaderUtils + */ + protected Class[] detectDefaultConfigurationClasses(Class declaringClass) { + return AnnotationConfigContextLoaderUtils + .detectDefaultConfigurationClasses(declaringClass); + } + + @Override + public ApplicationContext loadContext(String... locations) throws Exception { + throw new UnsupportedOperationException("SpringApplicationContextLoader " + + "does not support the loadContext(String...) method"); + } + + @Override + protected String[] getResourceSuffixes() { + return new String[] { "-context.xml", "Context.groovy" }; + } + + @Override + protected String getResourceSuffix() { + throw new IllegalStateException(); + } + + /** + * Inner class to configure {@link WebMergedContextConfiguration}. + */ + private static class WebConfigurer { + + private static final Class WEB_CONTEXT_CLASS = GenericWebApplicationContext.class; + + void configure(MergedContextConfiguration configuration, + SpringApplication application, + List> initializers) { + if (!TestAnnotations.isIntegrationTest(configuration)) { + WebMergedContextConfiguration webConfiguration = (WebMergedContextConfiguration) configuration; + addMockServletContext(initializers, webConfiguration); + application.setApplicationContextClass(WEB_CONTEXT_CLASS); + } + } + + private void addMockServletContext( + List> initializers, + WebMergedContextConfiguration webConfiguration) { + SpringBootMockServletContext servletContext = new SpringBootMockServletContext( + webConfiguration.getResourceBasePath()); + initializers.add(0, + new ServletContextApplicationContextInitializer(servletContext)); + } + + } + + /** + * {@link ApplicationContextInitializer} to setup test property source locations. + */ + private static class PropertySourceLocationsInitializer + implements ApplicationContextInitializer { + + private final String[] propertySourceLocations; + + PropertySourceLocationsInitializer(String[] propertySourceLocations) { + this.propertySourceLocations = propertySourceLocations; + } + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + TestPropertySourceUtils.addPropertiesFilesToEnvironment(applicationContext, + this.propertySourceLocations); + } + + } + + private static class TestAnnotations { + + public static boolean isIntegrationTest( + MergedContextConfiguration configuration) { + return (hasAnnotation(configuration, IntegrationTest.class) + || hasAnnotation(configuration, WebIntegrationTest.class)); + } + + private static boolean hasAnnotation(MergedContextConfiguration configuration, + Class annotation) { + return AnnotatedElementUtils.isAnnotated(configuration.getTestClass(), + annotation); + } + + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/package-info.java new file mode 100644 index 0000000000..9f71b0c3ba --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Classes and annotations related to configuring Spring's {@code ApplicationContext} for + * tests. + */ +package org.springframework.boot.test.context; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/WebAppIntegrationTestContextBootstrapper.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebAppIntegrationTestContextBootstrapper.java similarity index 82% rename from spring-boot-test/src/main/java/org/springframework/boot/test/WebAppIntegrationTestContextBootstrapper.java rename to spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebAppIntegrationTestContextBootstrapper.java index badc7288e8..2af5c5ba91 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/WebAppIntegrationTestContextBootstrapper.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebAppIntegrationTestContextBootstrapper.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.context.web; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.boot.test.context.MergedContextConfigurationProperties; +import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.test.context.ContextLoader; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.context.TestContextBootstrapper; @@ -35,7 +36,7 @@ class WebAppIntegrationTestContextBootstrapper extends DefaultTestContextBootstr @Override protected Class getDefaultContextLoaderClass( Class testClass) { - if (AnnotationUtils.findAnnotation(testClass, WebIntegrationTest.class) != null) { + if (AnnotatedElementUtils.isAnnotated(testClass, WebIntegrationTest.class)) { return WebDelegatingSmartContextLoader.class; } return super.getDefaultContextLoaderClass(testClass); @@ -44,8 +45,8 @@ class WebAppIntegrationTestContextBootstrapper extends DefaultTestContextBootstr @Override protected MergedContextConfiguration processMergedContextConfiguration( MergedContextConfiguration mergedConfig) { - WebIntegrationTest annotation = AnnotationUtils - .findAnnotation(mergedConfig.getTestClass(), WebIntegrationTest.class); + WebIntegrationTest annotation = AnnotatedElementUtils.findMergedAnnotation( + mergedConfig.getTestClass(), WebIntegrationTest.class); if (annotation != null) { mergedConfig = new WebMergedContextConfiguration(mergedConfig, null); MergedContextConfigurationProperties properties = new MergedContextConfigurationProperties( diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java new file mode 100644 index 0000000000..33b68f8e07 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/WebIntegrationTest.java @@ -0,0 +1,65 @@ +/* + * 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.context.web; + +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.core.env.Environment; +import org.springframework.test.context.BootstrapWith; + +/** + * Test class annotation signifying that the tests are "web integration tests" and + * therefore require full startup in the same way as a production application (listening + * on normal ports). Normally used in conjunction with + * {@code @SpringApplicationConfiguration}, + *

+ * This annotation can be used as an alternative to {@code @IntegrationTest} and + * {@code @WebAppConfiguration}. + * + * @author Phillip Webb + * @since 1.2.1 + * @see org.springframework.boot.test.context.IntegrationTest + */ +@Documented +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@BootstrapWith(WebAppIntegrationTestContextBootstrapper.class) +public @interface WebIntegrationTest { + + /** + * Properties in form {@literal key=value} that should be added to the Spring + * {@link Environment} before the test runs. + * @return properties to add to the context + */ + String[] value() default {}; + + /** + * Convenience attribute that can be used to set a {@code server.port=0} + * {@link Environment} property which usually triggers listening on a random port. + * Often used in conjunction with a @Value("${local.server.port}") + * injected field on the test. + * @return if a random port should be used + */ + boolean randomPort() default false; + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/package-info.java new file mode 100644 index 0000000000..69157a4551 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/web/package-info.java @@ -0,0 +1,21 @@ +/* + * 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. + */ + +/** + * Classes and annotations related to configuring Spring's {@code WebApplicationContext} + * for tests. + */ +package org.springframework.boot.test.context.web; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/SpringBootMockServletContext.java b/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/SpringBootMockServletContext.java new file mode 100644 index 0000000000..17aaee42ff --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/SpringBootMockServletContext.java @@ -0,0 +1,113 @@ +/* + * 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.mock.web; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import org.springframework.core.io.FileSystemResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.mock.web.MockServletContext; + +/** + * {@link MockServletContext} implementation for Spring Boot. Respects well know Spring + * Boot resource locations and uses an empty directory for "/" if no locations can be + * found. + * + * @author Phillip Webb + * @since 1.4.0 + */ +public class SpringBootMockServletContext extends MockServletContext { + + private static final String[] SPRING_BOOT_RESOURCE_LOCATIONS = new String[] { + "classpath:META-INF/resources", "classpath:resources", "classpath:static", + "classpath:public" }; + + private final ResourceLoader resourceLoader; + + private File emptyRootFolder; + + public SpringBootMockServletContext(String resourceBasePath) { + this(resourceBasePath, new FileSystemResourceLoader()); + } + + public SpringBootMockServletContext(String resourceBasePath, + ResourceLoader resourceLoader) { + super(resourceBasePath, resourceLoader); + this.resourceLoader = resourceLoader; + } + + @Override + protected String getResourceLocation(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + String resourceLocation = getResourceBasePathLocation(path); + if (exists(resourceLocation)) { + return resourceLocation; + } + for (String prefix : SPRING_BOOT_RESOURCE_LOCATIONS) { + resourceLocation = prefix + path; + if (exists(resourceLocation)) { + return resourceLocation; + } + } + return super.getResourceLocation(path); + } + + protected final String getResourceBasePathLocation(String path) { + return super.getResourceLocation(path); + } + + private boolean exists(String resourceLocation) { + try { + Resource resource = this.resourceLoader.getResource(resourceLocation); + return resource.exists(); + } + catch (Exception ex) { + return false; + } + } + + @Override + public URL getResource(String path) throws MalformedURLException { + URL resource = super.getResource(path); + if (resource == null && "/".equals(path)) { + // Liquibase assumes that "/" always exists, if we don't have a directory + // use a temporary location. + try { + if (this.emptyRootFolder == null) { + synchronized (this) { + File tempFolder = File.createTempFile("spr", "servlet"); + tempFolder.delete(); + tempFolder.mkdirs(); + tempFolder.deleteOnExit(); + this.emptyRootFolder = tempFolder; + } + } + return this.emptyRootFolder.toURI().toURL(); + } + catch (IOException ex) { + // Ignore + } + } + return resource; + } +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/package-info.java new file mode 100644 index 0000000000..aa4810f23f --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/mock/web/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Mock web classes specific to Spring Boot. + */ +package org.springframework.boot.test.mock.web; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/package-info.java index 3e2b2ee93b..c1e2ef06df 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/package-info.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/package-info.java @@ -15,8 +15,6 @@ */ /** - * Classes and utilities that are useful when unit-testing Spring Boot applications. This - * package is only intended for use in 'src/test' and should not be used in your - * 'src/main' code. + * Classes and utilities that are useful when unit-testing Spring Boot applications. */ package org.springframework.boot.test; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/rule/OutputCapture.java b/spring-boot-test/src/main/java/org/springframework/boot/test/rule/OutputCapture.java new file mode 100644 index 0000000000..ba3cc44b3e --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/rule/OutputCapture.java @@ -0,0 +1,197 @@ +/* + * 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.rule; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import org.hamcrest.Matcher; +import org.junit.Assert; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import org.springframework.boot.ansi.AnsiOutput; +import org.springframework.boot.ansi.AnsiOutput.Enabled; + +import static org.hamcrest.Matchers.allOf; + +/** + * JUnit {@code @Rule} to capture output from System.out and System.err. + * + * @author Phillip Webb + * @author Andy Wilkinson + * @since 1.4.0 + */ +public class OutputCapture implements TestRule { + + private CaptureOutputStream captureOut; + + private CaptureOutputStream captureErr; + + private ByteArrayOutputStream copy; + + private List> matchers = new ArrayList>(); + + @Override + public Statement apply(final Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + captureOutput(); + try { + base.evaluate(); + } + finally { + try { + if (!OutputCapture.this.matchers.isEmpty()) { + String output = OutputCapture.this.toString(); + Assert.assertThat(output, allOf(OutputCapture.this.matchers)); + } + } + finally { + releaseOutput(); + } + } + } + }; + } + + protected void captureOutput() { + AnsiOutputControl.get().disableAnsiOutput(); + this.copy = new ByteArrayOutputStream(); + this.captureOut = new CaptureOutputStream(System.out, this.copy); + this.captureErr = new CaptureOutputStream(System.err, this.copy); + System.setOut(new PrintStream(this.captureOut)); + System.setErr(new PrintStream(this.captureErr)); + } + + protected void releaseOutput() { + AnsiOutputControl.get().enabledAnsiOutput(); + System.setOut(this.captureOut.getOriginal()); + System.setErr(this.captureErr.getOriginal()); + this.copy = null; + } + + public void flush() { + try { + this.captureOut.flush(); + this.captureErr.flush(); + } + catch (IOException ex) { + // ignore + } + } + + @Override + public String toString() { + flush(); + return this.copy.toString(); + } + + /** + * Verify that the output is matched by the supplied {@code matcher}. Verification is + * performed after the test method has executed. + * @param matcher the matcher + */ + public void expect(Matcher matcher) { + this.matchers.add(matcher); + } + + private static class CaptureOutputStream extends OutputStream { + + private final PrintStream original; + + private final OutputStream copy; + + CaptureOutputStream(PrintStream original, OutputStream copy) { + this.original = original; + this.copy = copy; + } + + @Override + public void write(int b) throws IOException { + this.copy.write(b); + this.original.write(b); + this.original.flush(); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + this.copy.write(b, off, len); + this.original.write(b, off, len); + } + + public PrintStream getOriginal() { + return this.original; + } + + @Override + public void flush() throws IOException { + this.copy.flush(); + this.original.flush(); + } + + } + + /** + * Allow AnsiOutput to not be on the test classpath. + */ + private static class AnsiOutputControl { + + public void disableAnsiOutput() { + } + + public void enabledAnsiOutput() { + } + + public static AnsiOutputControl get() { + try { + Class.forName("org.springframework.boot.ansi.AnsiOutput"); + return new AnsiPresentOutputControl(); + } + catch (ClassNotFoundException ex) { + return new AnsiOutputControl(); + } + } + + } + + private static class AnsiPresentOutputControl extends AnsiOutputControl { + + @Override + public void disableAnsiOutput() { + AnsiOutput.setEnabled(Enabled.NEVER); + } + + @Override + public void enabledAnsiOutput() { + AnsiOutput.setEnabled(Enabled.DETECT); + } + + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/rule/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/rule/package-info.java new file mode 100644 index 0000000000..e6f530e250 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/rule/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Useful JUnit {@code @Rule} classes. + */ +package org.springframework.boot.test.rule; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/ApplicationContextTestUtils.java b/spring-boot-test/src/main/java/org/springframework/boot/test/util/ApplicationContextTestUtils.java similarity index 96% rename from spring-boot-test/src/main/java/org/springframework/boot/test/ApplicationContextTestUtils.java rename to spring-boot-test/src/main/java/org/springframework/boot/test/util/ApplicationContextTestUtils.java index 820d7538e2..58d7eeabce 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/ApplicationContextTestUtils.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/util/ApplicationContextTestUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.util; import org.springframework.context.ApplicationContext; import org.springframework.context.ConfigurableApplicationContext; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/util/EnvironmentTestUtils.java b/spring-boot-test/src/main/java/org/springframework/boot/test/util/EnvironmentTestUtils.java new file mode 100644 index 0000000000..b7cb4690bd --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/util/EnvironmentTestUtils.java @@ -0,0 +1,103 @@ +/* + * 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.util; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.MutablePropertySources; + +/** + * Test utilities for setting environment values. + * + * @author Dave Syer + * @author Stephane Nicoll + * @since 1.4.0 + */ +public abstract class EnvironmentTestUtils { + + /** + * Add additional (high priority) values to an {@link Environment} owned by an + * {@link ApplicationContext}. Name-value pairs can be specified with colon (":") or + * equals ("=") separators. + * @param context the context with an environment to modify + * @param pairs the name:value pairs + */ + public static void addEnvironment(ConfigurableApplicationContext context, + String... pairs) { + addEnvironment(context.getEnvironment(), pairs); + } + + /** + * Add additional (high priority) values to an {@link Environment}. Name-value pairs + * can be specified with colon (":") or equals ("=") separators. + * @param environment the environment to modify + * @param pairs the name:value pairs + */ + public static void addEnvironment(ConfigurableEnvironment environment, + String... pairs) { + addEnvironment("test", environment, pairs); + } + + /** + * Add additional (high priority) values to an {@link Environment}. Name-value pairs + * can be specified with colon (":") or equals ("=") separators. + * @param environment the environment to modify + * @param name the property source name + * @param pairs the name:value pairs + */ + public static void addEnvironment(String name, ConfigurableEnvironment environment, + String... pairs) { + MutablePropertySources sources = environment.getPropertySources(); + Map map = getOrAdd(sources, name); + for (String pair : pairs) { + int index = getSeparatorIndex(pair); + String key = pair.substring(0, index > 0 ? index : pair.length()); + String value = index > 0 ? pair.substring(index + 1) : ""; + map.put(key.trim(), value.trim()); + } + } + + @SuppressWarnings("unchecked") + private static Map getOrAdd(MutablePropertySources sources, + String name) { + if (sources.contains(name)) { + return (Map) sources.get(name).getSource(); + } + Map map = new HashMap(); + sources.addFirst(new MapPropertySource(name, map)); + return map; + } + + private static int getSeparatorIndex(String pair) { + int colonIndex = pair.indexOf(":"); + int equalIndex = pair.indexOf("="); + if (colonIndex == -1) { + return equalIndex; + } + if (equalIndex == -1) { + return colonIndex; + } + return Math.min(colonIndex, equalIndex); + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/util/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/util/package-info.java new file mode 100644 index 0000000000..fb11e15e73 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/util/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * General purpose test utilities. + */ +package org.springframework.boot.test.util; diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java new file mode 100644 index 0000000000..e61b3c633a --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java @@ -0,0 +1,175 @@ +/* + * 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.web.client; + +import java.io.IOException; +import java.net.URI; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.config.RequestConfig.Builder; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.protocol.HttpContext; + +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.http.client.InterceptingClientHttpRequestFactory; +import org.springframework.util.Base64Utils; +import org.springframework.util.ClassUtils; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.RestTemplate; + +/** + * Convenient subclass of {@link RestTemplate} that is suitable for integration tests. + * They are fault tolerant, and optionally can carry Basic authentication headers. If + * Apache Http Client 4.3.2 or better is available (recommended) it will be used as the + * client, and by default configured to ignore cookies and redirects. + * + * @author Dave Syer + * @author Phillip Webb + * @since 1.4.0 + */ +public class TestRestTemplate extends RestTemplate { + + private static final Charset UTF_8 = Charset.forName("UTF-8"); + + /** + * Create a new {@link TestRestTemplate} instance. + * @param httpClientOptions client options to use if the Apache HTTP Client is used + */ + public TestRestTemplate(HttpClientOption... httpClientOptions) { + this(null, null, httpClientOptions); + } + + /** + * Create a new {@link TestRestTemplate} instance with the specified credentials. + * @param username the username to use (or {@code null}) + * @param password the password (or {@code null}) + * @param httpClientOptions client options to use if the Apache HTTP Client is used + */ + public TestRestTemplate(String username, String password, + HttpClientOption... httpClientOptions) { + if (ClassUtils.isPresent("org.apache.http.client.config.RequestConfig", null)) { + setRequestFactory( + new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions)); + } + addAuthentication(username, password); + setErrorHandler(new DefaultResponseErrorHandler() { + @Override + public void handleError(ClientHttpResponse response) throws IOException { + } + }); + + } + + private void addAuthentication(String username, String password) { + if (username == null) { + return; + } + List interceptors = Collections + .singletonList( + new BasicAuthorizationInterceptor(username, password)); + setRequestFactory(new InterceptingClientHttpRequestFactory(getRequestFactory(), + interceptors)); + } + + /** + * Options used to customize the Apache Http Client if it is used. + */ + public enum HttpClientOption { + + /** + * Enable cookies. + */ + ENABLE_COOKIES, + + /** + * Enable redirects. + */ + ENABLE_REDIRECTS + + } + + private static class BasicAuthorizationInterceptor + implements ClientHttpRequestInterceptor { + + private final String username; + + private final String password; + + BasicAuthorizationInterceptor(String username, String password) { + this.username = username; + this.password = (password == null ? "" : password); + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + String token = Base64Utils.encodeToString( + (this.username + ":" + this.password).getBytes(UTF_8)); + request.getHeaders().add("Authorization", "Basic " + token); + return execution.execute(request, body); + } + + } + + /** + * {@link HttpComponentsClientHttpRequestFactory} to apply customizations. + */ + protected static class CustomHttpComponentsClientHttpRequestFactory + extends HttpComponentsClientHttpRequestFactory { + + private final String cookieSpec; + + private final boolean enableRedirects; + + public CustomHttpComponentsClientHttpRequestFactory( + HttpClientOption[] httpClientOptions) { + Set options = new HashSet( + Arrays.asList(httpClientOptions)); + this.cookieSpec = (options.contains(HttpClientOption.ENABLE_COOKIES) + ? CookieSpecs.STANDARD : CookieSpecs.IGNORE_COOKIES); + this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS); + } + + @Override + protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { + HttpClientContext context = HttpClientContext.create(); + context.setRequestConfig(getRequestConfig()); + return context; + } + + protected RequestConfig getRequestConfig() { + Builder builder = RequestConfig.custom().setCookieSpec(this.cookieSpec) + .setAuthenticationEnabled(false) + .setRedirectsEnabled(this.enableRedirects); + return builder.build(); + } + + } + +} diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java new file mode 100644 index 0000000000..a770b21dd6 --- /dev/null +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Web client test utilities. + */ +package org.springframework.boot.test.web.client; diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/ConfigFileApplicationContextInitializerTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/ConfigFileApplicationContextInitializerTests.java index 227415133b..9ac116859f 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/ConfigFileApplicationContextInitializerTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/ConfigFileApplicationContextInitializerTests.java @@ -36,6 +36,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @ContextConfiguration(classes = ConfigFileApplicationContextInitializerTests.Config.class, initializers = ConfigFileApplicationContextInitializer.class) +@Deprecated +@SuppressWarnings("deprecation") public class ConfigFileApplicationContextInitializerTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/EnvironmentTestUtilsTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/EnvironmentTestUtilsTests.java index 28a8b23ac5..85708988cd 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/EnvironmentTestUtilsTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/EnvironmentTestUtilsTests.java @@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Stephane Nicoll */ +@Deprecated public class EnvironmentTestUtilsTests { private final ConfigurableEnvironment environment = new StandardEnvironment(); diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationActiveProfileTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationActiveProfileTests.java index d9e93186be..de5e9422b3 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationActiveProfileTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationActiveProfileTests.java @@ -38,6 +38,8 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringApplicationConfiguration @IntegrationTest("spring.config.name=enableother") @ActiveProfiles("override") +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationConfigurationActiveProfileTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationDefaultConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationDefaultConfigurationTests.java index 8d66362035..01607f3ca3 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationDefaultConfigurationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationDefaultConfigurationTests.java @@ -34,6 +34,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @SpringApplicationConfiguration +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationConfigurationDefaultConfigurationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConfigurationTests.java index 034c2212b7..ad599231cf 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConfigurationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConfigurationTests.java @@ -33,6 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @SpringApplicationConfiguration(locations = "classpath:test.groovy") +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationConfigurationGroovyConfigurationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConventionConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConventionConfigurationTests.java index d02b44d1f9..ce93ce3f88 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConventionConfigurationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationGroovyConventionConfigurationTests.java @@ -33,6 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @SpringApplicationConfiguration +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationConfigurationGroovyConventionConfigurationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationJmxTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationJmxTests.java index da9a8173d5..977f452de2 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationJmxTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationJmxTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; @DirtiesContext @SpringApplicationConfiguration(Config.class) @IntegrationTest +@Deprecated public class SpringApplicationConfigurationJmxTests { @Value("${spring.jmx.enabled}") diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationMixedConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationMixedConfigurationTests.java index 5a35b18883..710e1e8c6a 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationMixedConfigurationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationMixedConfigurationTests.java @@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @SpringApplicationConfiguration(classes = Config.class, locations = "classpath:test.groovy") +@Deprecated public class SpringApplicationConfigurationMixedConfigurationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationXmlConventionConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationXmlConventionConfigurationTests.java index a4be713543..0cdf924002 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationXmlConventionConfigurationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationConfigurationXmlConventionConfigurationTests.java @@ -33,6 +33,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringJUnit4ClassRunner.class) @DirtiesContext @SpringApplicationConfiguration +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationConfigurationXmlConventionConfigurationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationContextLoaderTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationContextLoaderTests.java index 56959c25fa..bca6cf40a8 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationContextLoaderTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationContextLoaderTests.java @@ -36,6 +36,8 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Stephane Nicoll */ +@Deprecated +@SuppressWarnings("deprecation") public class SpringApplicationContextLoaderTests { @Test diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestPropertyLocationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestPropertyLocationTests.java index 95b610192b..877b658337 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestPropertyLocationTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestPropertyLocationTests.java @@ -45,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat; @WebAppConfiguration @IntegrationTest({ "server.port=0", "value1=123" }) @TestPropertySource(properties = "value2=456", locations = "classpath:/test-property-source-annotation.properties") +@Deprecated public class SpringApplicationIntegrationTestPropertyLocationTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestTests.java index 2c05b22b54..de1907cbb2 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationIntegrationTestTests.java @@ -53,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringApplicationConfiguration(Config.class) @WebAppConfiguration @IntegrationTest({ "server.port=0", "value=123" }) +@Deprecated public class SpringApplicationIntegrationTestTests { @LocalServerPort diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationMockMvcTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationMockMvcTests.java index 64e088aeef..38149617a5 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationMockMvcTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationMockMvcTests.java @@ -50,6 +50,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @DirtiesContext @SpringApplicationConfiguration(classes = Config.class) @WebAppConfiguration +@Deprecated public class SpringApplicationMockMvcTests { @Autowired diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationWebIntegrationTestTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationWebIntegrationTestTests.java index d3a6f5e984..debab7f779 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationWebIntegrationTestTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringApplicationWebIntegrationTestTests.java @@ -51,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat; @DirtiesContext @SpringApplicationConfiguration(Config.class) @WebIntegrationTest({ "server.port=0", "value=123" }) +@Deprecated public class SpringApplicationWebIntegrationTestTests { @LocalServerPort diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringBootMockServletContextTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringBootMockServletContextTests.java index e3a6e9ed0b..c1ebe916a6 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/SpringBootMockServletContextTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/SpringBootMockServletContextTests.java @@ -45,6 +45,8 @@ import static org.hamcrest.Matchers.nullValue; @DirtiesContext @SpringApplicationConfiguration(SpringBootMockServletContextTests.Config.class) @WebAppConfiguration("src/test/webapp") +@Deprecated +@SuppressWarnings("deprecation") public class SpringBootMockServletContextTests implements ServletContextAware { private ServletContext servletContext; diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializerTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializerTests.java new file mode 100644 index 0000000000..60f732ae85 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/ConfigFileApplicationContextInitializerTests.java @@ -0,0 +1,53 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ConfigFileApplicationContextInitializer}. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@ContextConfiguration(classes = ConfigFileApplicationContextInitializerTests.Config.class, initializers = ConfigFileApplicationContextInitializer.class) +public class ConfigFileApplicationContextInitializerTests { + + @Autowired + private Environment environment; + + @Test + public void initializerPopulatesEnvironment() { + assertThat(this.environment.getProperty("foo")).isEqualTo("bucket"); + } + + @Configuration + public static class Config { + + } +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationActiveProfileTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationActiveProfileTests.java new file mode 100644 index 0000000000..39c2695819 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationActiveProfileTests.java @@ -0,0 +1,57 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} with active profiles. See gh-1469. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration +@IntegrationTest("spring.config.name=enableother") +@ActiveProfiles("override") +public class SpringApplicationConfigurationActiveProfileTests { + + @Autowired + private ApplicationContext context; + + @Test + public void profiles() throws Exception { + assertThat(this.context.getEnvironment().getActiveProfiles()) + .containsExactly("override"); + } + + @Configuration + protected static class Config { + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationDefaultConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationDefaultConfigurationTests.java new file mode 100644 index 0000000000..34d175f411 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationDefaultConfigurationTests.java @@ -0,0 +1,52 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} (detectDefaultConfigurationClasses). + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration +public class SpringApplicationConfigurationDefaultConfigurationTests { + + @Autowired + private Config config; + + @Test + public void nestedConfigClasses() { + assertThat(this.config).isNotNull(); + } + + @Configuration + protected static class Config { + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConfigurationTests.java new file mode 100644 index 0000000000..ffde9a38fe --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConfigurationTests.java @@ -0,0 +1,46 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} (detectDefaultConfigurationClasses). + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(locations = "classpath:test.groovy") +public class SpringApplicationConfigurationGroovyConfigurationTests { + + @Autowired + private String foo; + + @Test + public void groovyConfigLoaded() { + assertThat(this.foo).isNotNull(); + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTests.java new file mode 100644 index 0000000000..7ba3ebd704 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTests.java @@ -0,0 +1,46 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} finding groovy config. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration +public class SpringApplicationConfigurationGroovyConventionConfigurationTests { + + @Autowired + private String foo; + + @Test + public void groovyConfigLoaded() { + assertThat(this.foo).isEqualTo("World"); + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationJmxTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationJmxTests.java new file mode 100644 index 0000000000..7503567f3d --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationJmxTests.java @@ -0,0 +1,61 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringApplicationConfigurationJmxTests.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for disabling JMX by default + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(Config.class) +@IntegrationTest +public class SpringApplicationConfigurationJmxTests { + + @Value("${spring.jmx.enabled}") + private boolean jmx; + + @Test + public void disabledByDefault() { + assertThat(this.jmx).isFalse(); + } + + @Configuration + protected static class Config { + + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationMixedConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationMixedConfigurationTests.java new file mode 100644 index 0000000000..319991fa93 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationMixedConfigurationTests.java @@ -0,0 +1,57 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringApplicationConfigurationMixedConfigurationTests.Config; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader}. + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(classes = Config.class, locations = "classpath:test.groovy") +public class SpringApplicationConfigurationMixedConfigurationTests { + + @Autowired + private String foo; + + @Autowired + private Config config; + + @Test + public void mixedConfigClasses() { + assertThat(this.foo).isNotNull(); + assertThat(this.config).isNotNull(); + } + + @Configuration + protected static class Config { + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests.java new file mode 100644 index 0000000000..5b50822382 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests.java @@ -0,0 +1,46 @@ +/* + * 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.context; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} finding XML config. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration +public class SpringApplicationConfigurationXmlConventionConfigurationTests { + + @Autowired + private String foo; + + @Test + public void xmlConfigLoaded() { + assertThat(this.foo).isEqualTo("World"); + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationContextLoaderTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationContextLoaderTests.java new file mode 100644 index 0000000000..7a2c389b34 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationContextLoaderTests.java @@ -0,0 +1,156 @@ +/* + * 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.context; + +import java.util.Map; + +import org.junit.Ignore; +import org.junit.Test; + +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.MergedContextConfiguration; +import org.springframework.test.context.TestContext; +import org.springframework.test.context.TestContextManager; +import org.springframework.test.context.support.TestPropertySourceUtils; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringApplicationContextLoader} + * + * @author Stephane Nicoll + */ +public class SpringApplicationContextLoaderTests { + + @Test + public void environmentPropertiesSimple() throws Exception { + Map config = getEnvironmentProperties(SimpleConfig.class); + assertKey(config, "key", "myValue"); + assertKey(config, "anotherKey", "anotherValue"); + } + + @Test + public void environmentPropertiesOverrideDefaults() throws Exception { + Map config = getEnvironmentProperties(OverrideConfig.class); + assertKey(config, "server.port", "2345"); + } + + @Test + public void environmentPropertiesAppend() throws Exception { + Map config = getEnvironmentProperties(AppendConfig.class); + assertKey(config, "key", "myValue"); + assertKey(config, "otherKey", "otherValue"); + } + + @Test + public void environmentPropertiesSeparatorInValue() throws Exception { + Map config = getEnvironmentProperties(SameSeparatorInValue.class); + assertKey(config, "key", "my=Value"); + assertKey(config, "anotherKey", "another:Value"); + } + + @Test + public void environmentPropertiesAnotherSeparatorInValue() throws Exception { + Map config = getEnvironmentProperties( + AnotherSeparatorInValue.class); + assertKey(config, "key", "my:Value"); + assertKey(config, "anotherKey", "another=Value"); + } + + @Test + @Ignore + public void environmentPropertiesNewLineInValue() throws Exception { + // gh-4384 + Map config = getEnvironmentProperties(NewLineInValue.class); + assertKey(config, "key", "myValue"); + assertKey(config, "variables", "foo=FOO\n bar=BAR"); + } + + private Map getEnvironmentProperties(Class testClass) + throws Exception { + TestContext context = new ExposedTestContextManager(testClass) + .getExposedTestContext(); + MergedContextConfiguration config = (MergedContextConfiguration) ReflectionTestUtils + .getField(context, "mergedContextConfiguration"); + return TestPropertySourceUtils + .convertInlinedPropertiesToMap(config.getPropertySourceProperties()); + } + + private void assertKey(Map actual, String key, Object value) { + assertThat(actual.containsKey(key)).as("Key '" + key + "' not found").isTrue(); + assertThat(actual.get(key)).isEqualTo(value); + } + + @IntegrationTest({ "key=myValue", "anotherKey:anotherValue" }) + @ContextConfiguration(classes = Config.class) + static class SimpleConfig { + + } + + @IntegrationTest({ "server.port=2345" }) + @ContextConfiguration(classes = Config.class) + static class OverrideConfig { + + } + + @IntegrationTest({ "key=myValue", "otherKey=otherValue" }) + @ContextConfiguration(classes = Config.class) + static class AppendConfig { + + } + + @IntegrationTest({ "key=my=Value", "anotherKey:another:Value" }) + @ContextConfiguration(classes = Config.class) + static class SameSeparatorInValue { + + } + + @IntegrationTest({ "key=my:Value", "anotherKey:another=Value" }) + @ContextConfiguration(classes = Config.class) + static class AnotherSeparatorInValue { + + } + + @IntegrationTest({ "key=myValue", "variables=foo=FOO\n bar=BAR" }) + @ContextConfiguration(classes = Config.class) + static class NewLineInValue { + + } + + @Configuration + static class Config { + + } + + /** + * {@link TestContextManager} which exposes the {@link TestContext}. + */ + private static class ExposedTestContextManager extends TestContextManager { + + ExposedTestContextManager(Class testClass) { + super(testClass); + } + + public final TestContext getExposedTestContext() { + return super.getTestContext(); + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestPropertyLocationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestPropertyLocationTests.java new file mode 100644 index 0000000000..99ad9d2dae --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestPropertyLocationTests.java @@ -0,0 +1,82 @@ +/* + * 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.context; + +import javax.annotation.PostConstruct; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringApplicationIntegrationTestPropertyLocationTests.MoreConfig; +import org.springframework.boot.test.context.SpringApplicationIntegrationTestTests.Config; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link IntegrationTest} with {@link TestPropertySource} locations. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration({ Config.class, MoreConfig.class }) +@WebAppConfiguration +@IntegrationTest({ "server.port=0", "value1=123" }) +@TestPropertySource(properties = "value2=456", locations = "classpath:/test-property-source-annotation.properties") +public class SpringApplicationIntegrationTestPropertyLocationTests { + + @Autowired + private Environment environment; + + @Test + public void loadedProperties() throws Exception { + assertThat(this.environment.getProperty("value1")).isEqualTo("123"); + assertThat(this.environment.getProperty("value2")).isEqualTo("456"); + assertThat(this.environment.getProperty("annotation-referenced")) + .isEqualTo("fromfile"); + } + + @Configuration + static class MoreConfig { + + @Value("${value1}") + private String value1; + + @Value("${value2}") + private String value2; + + @Value("${annotation-referenced}") + private String annotationReferenced; + + @PostConstruct + void checkValues() { + assertThat(this.value1).isEqualTo("123"); + assertThat(this.value2).isEqualTo("456"); + assertThat(this.annotationReferenced).isEqualTo("fromfile"); + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestTests.java new file mode 100644 index 0000000000..9346b8b787 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringApplicationIntegrationTestTests.java @@ -0,0 +1,120 @@ +/* + * 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.context; + +import javax.servlet.ServletContext; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; +import org.springframework.boot.test.context.SpringApplicationIntegrationTestTests.Config; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link IntegrationTest} + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(Config.class) +@WebAppConfiguration +@IntegrationTest({ "server.port=0", "value=123" }) +public class SpringApplicationIntegrationTestTests { + + @Value("${local.server.port}") + private int port = 0; + + @Value("${value}") + private int value = 0; + + @Autowired + private WebApplicationContext context; + + @Autowired + private ServletContext servletContext; + + @Test + public void runAndTestHttpEndpoint() { + assertThat(this.port).isNotEqualTo(8080).isNotEqualTo(0); + String body = new RestTemplate() + .getForObject("http://localhost:" + this.port + "/", String.class); + assertThat(body).isEqualTo("Hello World"); + } + + @Test + public void annotationAttributesOverridePropertiesFile() throws Exception { + assertThat(this.value).isEqualTo(123); + } + + @Test + public void validateWebApplicationContextIsSet() { + assertThat(this.context).isSameAs( + WebApplicationContextUtils.getWebApplicationContext(this.servletContext)); + } + + @Configuration + @EnableWebMvc + @RestController + protected static class Config { + + @Value("${server.port:8080}") + private int port = 8080; + + @Bean + public DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + + @Bean + public EmbeddedServletContainerFactory embeddedServletContainer() { + TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); + factory.setPort(this.port); + return factory; + } + + @Bean + public static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationMockMvcTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationMockMvcTests.java new file mode 100644 index 0000000000..707d7a13bf --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationMockMvcTests.java @@ -0,0 +1,93 @@ +/* + * 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.context.web; + +import javax.servlet.ServletContext; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringApplicationConfiguration; +import org.springframework.boot.test.context.web.SpringApplicationMockMvcTests.Config; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +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 WebAppConfiguration} integration. + * + * @author Stephane Nicoll + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(classes = Config.class) +@WebAppConfiguration +public class SpringApplicationMockMvcTests { + + @Autowired + private WebApplicationContext context; + + @Autowired + private ServletContext servletContext; + + private MockMvc mvc; + + @Before + public void setUp() { + this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + } + + @Test + public void testMockHttpEndpoint() throws Exception { + this.mvc.perform(get("/")).andExpect(status().isOk()) + .andExpect(content().string("Hello World")); + } + + @Test + public void validateWebApplicationContextIsSet() { + assertThat(this.context).isSameAs( + WebApplicationContextUtils.getWebApplicationContext(this.servletContext)); + } + + @Configuration + @EnableWebMvc + @RestController + protected static class Config { + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationWebIntegrationTestTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationWebIntegrationTestTests.java new file mode 100644 index 0000000000..d170894e40 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/web/SpringApplicationWebIntegrationTestTests.java @@ -0,0 +1,131 @@ +/* + * 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.context.web; + +import javax.servlet.ServletContext; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; +import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; +import org.springframework.boot.context.web.LocalServerPort; +import org.springframework.boot.test.context.IntegrationTest; +import org.springframework.boot.test.context.SpringApplicationConfiguration; +import org.springframework.boot.test.context.web.SpringApplicationWebIntegrationTestTests.Config; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.springframework.web.servlet.DispatcherServlet; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link IntegrationTest} + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(Config.class) +@WebIntegrationTest({ "server.port=0", "value=123" }) +public class SpringApplicationWebIntegrationTestTests { + + @LocalServerPort + private int port = 0; + + @Value("${value}") + private int value = 0; + + @Autowired + private WebApplicationContext context; + + @Autowired + private ServletContext servletContext; + + @Autowired + private TestRestTemplate restTemplate; + + @Test + public void runAndTestHttpEndpoint() { + assertThat(this.port).isNotEqualTo(8080).isNotEqualTo(0); + String body = new RestTemplate() + .getForObject("http://localhost:" + this.port + "/", String.class); + assertThat(body).isEqualTo("Hello World"); + } + + @Test + public void injectTestRestTemplate() { + String body = this.restTemplate.getForObject("/", String.class); + assertThat(body).isEqualTo("Hello World"); + } + + @Test + public void annotationAttributesOverridePropertiesFile() throws Exception { + assertThat(this.value).isEqualTo(123); + } + + @Test + public void validateWebApplicationContextIsSet() { + assertThat(this.context).isSameAs( + WebApplicationContextUtils.getWebApplicationContext(this.servletContext)); + } + + @Configuration + @EnableWebMvc + @RestController + protected static class Config { + + @Value("${server.port:8080}") + private int port = 8080; + + @Bean + public DispatcherServlet dispatcherServlet() { + return new DispatcherServlet(); + } + + @Bean + public EmbeddedServletContainerFactory embeddedServletContainer() { + TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); + factory.setPort(this.port); + return factory; + } + + @Bean + public static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/mock/web/SpringBootMockServletContextTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/mock/web/SpringBootMockServletContextTests.java new file mode 100644 index 0000000000..8693299b67 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/mock/web/SpringBootMockServletContextTests.java @@ -0,0 +1,105 @@ +/* + * 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.mock.web; + +import java.io.File; +import java.io.FilenameFilter; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLDecoder; + +import javax.servlet.ServletContext; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.test.context.SpringApplicationConfiguration; +import org.springframework.boot.test.mock.web.SpringBootMockServletContextTests.Config; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.context.ServletContextAware; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.nullValue; + +/** + * Tests for {@link SpringBootMockServletContext}. + * + * @author Phillip Webb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +@SpringApplicationConfiguration(Config.class) +@WebAppConfiguration("src/test/webapp") +public class SpringBootMockServletContextTests implements ServletContextAware { + + private ServletContext servletContext; + + @Override + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + @Test + public void getResourceLocation() 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); + } + + // gh-2654 + @Test + public void getRootUrlExistsAndIsEmpty() throws Exception { + SpringBootMockServletContext context = new SpringBootMockServletContext( + "src/test/doesntexist") { + @Override + protected String getResourceLocation(String path) { + // Don't include the Spring Boot defaults for this test + return getResourceBasePathLocation(path); + }; + }; + URL resource = context.getResource("/"); + assertThat(resource).isNotEqualTo(nullValue()); + File file = new File(URLDecoder.decode(resource.getPath(), "UTF-8")); + assertThat(file).exists().isDirectory(); + String[] contents = file.list(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return !(".".equals(name) || "..".equals(name)); + } + }); + assertThat(contents).isNotEqualTo(nullValue()); + assertThat(contents.length).isEqualTo(0); + } + + @Configuration + static class Config { + + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/AbstractConfigurationClassTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/testutil/AbstractConfigurationClassTests.java similarity index 98% rename from spring-boot-test/src/test/java/org/springframework/boot/test/AbstractConfigurationClassTests.java rename to spring-boot-test/src/test/java/org/springframework/boot/test/testutil/AbstractConfigurationClassTests.java index 0e6d04aaa8..ac70525042 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/AbstractConfigurationClassTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/testutil/AbstractConfigurationClassTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.testutil; import java.io.File; import java.io.IOException; diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/ApplicationContextTestUtilsTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/util/ApplicationContextTestUtilsTests.java similarity index 97% rename from spring-boot-test/src/test/java/org/springframework/boot/test/ApplicationContextTestUtilsTests.java rename to spring-boot-test/src/test/java/org/springframework/boot/test/util/ApplicationContextTestUtilsTests.java index c54e5bff59..308d6cd58e 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/ApplicationContextTestUtilsTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/util/ApplicationContextTestUtilsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.util; import org.junit.Test; diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/util/EnvironmentTestUtilsTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/util/EnvironmentTestUtilsTests.java new file mode 100644 index 0000000000..a4e4e42a59 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/util/EnvironmentTestUtilsTests.java @@ -0,0 +1,95 @@ +/* + * 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.util; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.StandardEnvironment; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link EnvironmentTestUtils}. + * + * @author Stephane Nicoll + */ +public class EnvironmentTestUtilsTests { + + private final ConfigurableEnvironment environment = new StandardEnvironment(); + + @Test + public void addSimplePairEqual() { + testAddSimplePair("my.foo", "bar", "="); + } + + @Test + public void addSimplePairColon() { + testAddSimplePair("my.foo", "bar", ":"); + } + + @Test + public void addSimplePairEqualWithEqualInValue() { + testAddSimplePair("my.foo", "b=ar", "="); + } + + @Test + public void addSimplePairEqualWithColonInValue() { + testAddSimplePair("my.foo", "b:ar", "="); + } + + @Test + public void addSimplePairColonWithColonInValue() { + testAddSimplePair("my.foo", "b:ar", ":"); + } + + @Test + public void addSimplePairColonWithEqualInValue() { + testAddSimplePair("my.foo", "b=ar", ":"); + } + + @Test + public void addPairNoValue() { + String propertyName = "my.foo+bar"; + assertThat(this.environment.containsProperty(propertyName)).isFalse(); + EnvironmentTestUtils.addEnvironment(this.environment, propertyName); + assertThat(this.environment.containsProperty(propertyName)).isTrue(); + assertThat(this.environment.getProperty(propertyName)).isEqualTo(""); + } + + private void testAddSimplePair(String key, String value, String delimiter) { + assertThat(this.environment.containsProperty(key)).isFalse(); + EnvironmentTestUtils.addEnvironment(this.environment, key + delimiter + value); + assertThat(this.environment.getProperty(key)).isEqualTo(value); + } + + @Test + public void testConfigHasHigherPrecedence() { + Map map = new HashMap(); + map.put("my.foo", "bar"); + MapPropertySource source = new MapPropertySource("sample", map); + this.environment.getPropertySources().addFirst(source); + assertThat(this.environment.getProperty("my.foo")).isEqualTo("bar"); + EnvironmentTestUtils.addEnvironment(this.environment, "my.foo=bar2"); + assertThat(this.environment.getProperty("my.foo")).isEqualTo("bar2"); + } + +} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/TestRestTemplateTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java similarity index 88% rename from spring-boot-test/src/test/java/org/springframework/boot/test/TestRestTemplateTests.java rename to spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java index 47cc610423..4200dcd1b6 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/TestRestTemplateTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.boot.test; +package org.springframework.boot.test.web.client; import org.apache.http.client.config.RequestConfig; import org.junit.Test; -import org.springframework.boot.test.TestRestTemplate.CustomHttpComponentsClientHttpRequestFactory; -import org.springframework.boot.test.TestRestTemplate.HttpClientOption; +import org.springframework.boot.test.web.client.TestRestTemplate.CustomHttpComponentsClientHttpRequestFactory; +import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.InterceptingClientHttpRequestFactory; diff --git a/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTestsContext.groovy b/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTestsContext.groovy new file mode 100644 index 0000000000..a0c755956c --- /dev/null +++ b/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationGroovyConventionConfigurationTestsContext.groovy @@ -0,0 +1,3 @@ +beans { + foo String, "World" +} diff --git a/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests-context.xml b/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests-context.xml new file mode 100644 index 0000000000..a25ca5b996 --- /dev/null +++ b/spring-boot-test/src/test/resources/org/springframework/boot/test/context/SpringApplicationConfigurationXmlConventionConfigurationTests-context.xml @@ -0,0 +1,13 @@ + + + + + + World + + + +