diff --git a/pom.xml b/pom.xml index 798fd20499e..34696500964 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,7 @@ spring-boot spring-boot-test spring-boot-autoconfigure + spring-boot-test-autoconfigure spring-boot-actuator spring-boot-devtools spring-boot-docs diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index e1dd18c0b47..9cd46fbaaec 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -193,6 +193,11 @@ spring-boot-test 1.4.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-test-autoconfigure + 1.4.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-test diff --git a/spring-boot-full-build/pom.xml b/spring-boot-full-build/pom.xml index eb02ebd9578..1cee9f17cbb 100644 --- a/spring-boot-full-build/pom.xml +++ b/spring-boot-full-build/pom.xml @@ -51,6 +51,7 @@ ../spring-boot ../spring-boot-test ../spring-boot-autoconfigure + ../spring-boot-test-autoconfigure ../spring-boot-actuator ../spring-boot-actuator-docs ../spring-boot-devtools diff --git a/spring-boot-starters/spring-boot-starter-test/pom.xml b/spring-boot-starters/spring-boot-starter-test/pom.xml index e921b239ee5..b8c00311692 100644 --- a/spring-boot-starters/spring-boot-starter-test/pom.xml +++ b/spring-boot-starters/spring-boot-starter-test/pom.xml @@ -22,6 +22,10 @@ org.springframework.boot spring-boot-test + + org.springframework.boot + spring-boot-test-autoconfigure + com.jayway.jsonpath json-path diff --git a/spring-boot-test-autoconfigure/pom.xml b/spring-boot-test-autoconfigure/pom.xml new file mode 100644 index 00000000000..642446151eb --- /dev/null +++ b/spring-boot-test-autoconfigure/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-parent + 1.4.0.BUILD-SNAPSHOT + ../spring-boot-parent + + spring-boot-test-autoconfigure + Spring Boot Test Auto-Configure + Spring Boot Test Auto-Configure + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/.. + + + + + org.springframework.boot + spring-boot-test + + + org.springframework.boot + spring-boot-autoconfigure + + + + org.springframework + spring-test + true + + + + org.aspectj + aspectjrt + test + + + org.aspectj + aspectjweaver + test + + + ch.qos.logback + logback-classic + test + + + diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfiguration.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfiguration.java new file mode 100644 index 00000000000..9ad37b1811b --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfiguration.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; + +/** + * Annotation that can be used to override + * {@link EnableAutoConfiguration @EnableAutoConfiguration}. Often used in combination + * with {@link ImportAutoConfiguration} to limit the auto-configutation classes that are + * loaded. + * + * @author Phillip Webb + * @since 1.4.0 + * @see EnableAutoConfiguration#ENABLED_OVERRIDE_PROPERTY + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface OverrideAutoConfiguration { + + /** + * The value of the {@link EnableAutoConfiguration#ENABLED_OVERRIDE_PROPERTY enabled + * property override}. + */ + boolean enabled(); + +} diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactory.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactory.java new file mode 100644 index 00000000000..f1f6d29719c --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactory.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import java.util.List; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.annotation.AnnotatedElementUtils; +import org.springframework.test.context.ContextConfigurationAttributes; +import org.springframework.test.context.ContextCustomizer; +import org.springframework.test.context.ContextCustomizerFactory; +import org.springframework.test.context.MergedContextConfiguration; + +/** + * {@link ContextCustomizerFactory} to support + * {@link OverrideAutoConfiguration @OverrideAutoConfiguration}. + * + * @author Phillip Webb + */ +class OverrideAutoConfigurationContextCustomizerFactory + implements ContextCustomizerFactory { + + @Override + public ContextCustomizer createContextCustomizer(Class testClass, + List configurationAttributes) { + OverrideAutoConfiguration annotation = AnnotatedElementUtils + .findMergedAnnotation(testClass, OverrideAutoConfiguration.class); + if (annotation != null && !annotation.enabled()) { + return new DisableAutoConfigurationContextCustomizer(); + } + return null; + } + + /** + * {@link ContextCustomizer} to disable full auto-configuration. + */ + private static class DisableAutoConfigurationContextCustomizer + implements ContextCustomizer { + + @Override + public void customizeContext(ConfigurableApplicationContext context, + MergedContextConfiguration mergedConfig) { + EnvironmentTestUtils.addEnvironment(context, + EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY + "=false"); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return (obj != null && obj.getClass() == getClass()); + } + + } + +} diff --git a/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/package-info.java b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/package-info.java new file mode 100644 index 00000000000..e334c01a8d4 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/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. + */ + +/** + * Test auto-configuration support. + */ +package org.springframework.boot.test.autoconfigure; diff --git a/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000000..b8b5a325317 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories @@ -0,0 +1,7 @@ +# Spring Test ContextCustomizerFactories +org.springframework.test.context.ContextCustomizerFactory=\ +org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory + +# Test Execution Listeners +org.springframework.test.context.TestExecutionListener=\ +org.springframework.boot.test.autoconfigure.AutoConfigureReportTestExecutionListener diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleSpringBootApplication.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleSpringBootApplication.java new file mode 100644 index 00000000000..efe6de90d37 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleSpringBootApplication.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Example {@link SpringBootApplication @SpringBootApplication} for use with + * {@link OverrideAutoConfiguration} tests. + * + * @author Phillip Webb + */ +@SpringBootConfiguration +@EnableAutoConfiguration +public class ExampleSpringBootApplication { + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleTestConfig.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleTestConfig.java new file mode 100644 index 00000000000..9457cbdc7ef --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/ExampleTestConfig.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import org.springframework.boot.test.context.TestConfiguration; + +/** + * Example {@link TestConfiguration @TestConfiguration} for + * {@link OverrideAutoConfiguration} tests. + * + * @author Phillip Webb + */ +@TestConfiguration +public class ExampleTestConfig { + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactoryTests.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactoryTests.java new file mode 100644 index 00000000000..0de7f98f2cb --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationContextCustomizerFactoryTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import org.junit.Test; + +import org.springframework.test.context.ContextCustomizer; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OverrideAutoConfigurationContextCustomizerFactory}. + * + * @author pwebb + */ +public class OverrideAutoConfigurationContextCustomizerFactoryTests { + + private OverrideAutoConfigurationContextCustomizerFactory factory = new OverrideAutoConfigurationContextCustomizerFactory(); + + @Test + public void getContextCustomizerWhenHasNoAnnotationShouldReturnNull() + throws Exception { + ContextCustomizer customizer = this.factory + .createContextCustomizer(NoAnnotation.class, null); + assertThat(customizer).isNull(); + } + + @Test + public void getContextCustomizerWhenHasAnnotationEnabledTrueShouldReturnNull() + throws Exception { + ContextCustomizer customizer = this.factory + .createContextCustomizer(WithAnnotationEnabledTrue.class, null); + assertThat(customizer).isNull(); + } + + @Test + public void getContextCustomizerWhenHasAnnotationEnabledFalseShouldReturnCustomizer() + throws Exception { + ContextCustomizer customizer = this.factory + .createContextCustomizer(WithAnnotationEnabledFalse.class, null); + assertThat(customizer).isNotNull(); + } + + @Test + public void hashCodeAndEquals() throws Exception { + ContextCustomizer customizer1 = this.factory + .createContextCustomizer(WithAnnotationEnabledFalse.class, null); + ContextCustomizer customizer2 = this.factory + .createContextCustomizer(WithSameAnnotation.class, null); + assertThat(customizer1.hashCode()).isEqualTo(customizer2.hashCode()); + assertThat(customizer1).isEqualTo(customizer1).isEqualTo(customizer2); + } + + static class NoAnnotation { + + } + + @OverrideAutoConfiguration(enabled = true) + static class WithAnnotationEnabledTrue { + + } + + @OverrideAutoConfiguration(enabled = false) + static class WithAnnotationEnabledFalse { + + } + + @OverrideAutoConfiguration(enabled = false) + static class WithSameAnnotation { + + } + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledFalseIntegrationTest.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledFalseIntegrationTest.java new file mode 100644 index 00000000000..95ca0dae260 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledFalseIntegrationTest.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.autoconfigure; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; +import org.springframework.boot.test.context.SpringBootTestContextBootstrapper; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.BootstrapWith; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link OverrideAutoConfiguration} when {@code enabled} is + * {@code false}. + * + * @author Phillip Webb + */ +@RunWith(SpringRunner.class) +@OverrideAutoConfiguration(enabled = false) +@BootstrapWith(SpringBootTestContextBootstrapper.class) +@ImportAutoConfiguration(ExampleTestConfig.class) +public class OverrideAutoConfigurationEnabledFalseIntegrationTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Autowired + private ApplicationContext context; + + @Test + public void disabledAutoConfiguration() throws Exception { + ApplicationContext context = this.context; + assertThat(context.getBean(ExampleTestConfig.class)).isNotNull(); + this.thrown.expect(NoSuchBeanDefinitionException.class); + context.getBean(ConfigurationPropertiesBindingPostProcessor.class); + } + +} diff --git a/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledTrueIntegrationTest.java b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledTrueIntegrationTest.java new file mode 100644 index 00000000000..9997f6269f8 --- /dev/null +++ b/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/OverrideAutoConfigurationEnabledTrueIntegrationTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.test.autoconfigure; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; +import org.springframework.boot.test.context.SpringBootTestContextBootstrapper; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.BootstrapWith; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link OverrideAutoConfiguration} when {@code enabled} is + * {@code true}. + * + * @author Phillip Webb + */ +@RunWith(SpringRunner.class) +@OverrideAutoConfiguration(enabled = true) +@BootstrapWith(SpringBootTestContextBootstrapper.class) +@ImportAutoConfiguration(ExampleTestConfig.class) +public class OverrideAutoConfigurationEnabledTrueIntegrationTest { + + @Autowired + private ApplicationContext context; + + @Test + public void autoconfiguredContext() throws Exception { + ApplicationContext context = this.context; + assertThat(context.getBean(ExampleSpringBootApplication.class)).isNotNull(); + assertThat(context.getBean(ConfigurationPropertiesBindingPostProcessor.class)) + .isNotNull(); + } + +}