/* * 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.autoconfigure.condition; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.isA; /** * Tests for {@link ConditionalOnSingleCandidate}. * * @author Stephane Nicoll * @author Andy Wilkinson */ public class ConditionalOnSingleCandidateTests { @Rule public final ExpectedException thrown = ExpectedException.none(); private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); @After public void close() { if (this.context != null) { this.context.close(); } } @Test public void singleCandidateNoCandidate() { load(OnBeanSingleCandidateConfiguration.class); assertThat(this.context.containsBean("baz")).isFalse(); } @Test public void singleCandidateOneCandidate() { load(FooConfiguration.class, OnBeanSingleCandidateConfiguration.class); assertThat(this.context.containsBean("baz")).isTrue(); assertThat(this.context.getBean("baz")).isEqualTo("foo"); } @Test public void singleCandidateInAncestorsOneCandidateInCurrent() { load(); AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); child.register(FooConfiguration.class, OnBeanSingleCandidateInAncestorsConfiguration.class); child.setParent(this.context); child.refresh(); assertThat(child.containsBean("baz")).isFalse(); child.close(); } @Test public void singleCandidateInAncestorsOneCandidateInParent() { load(FooConfiguration.class); AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); child.register(OnBeanSingleCandidateInAncestorsConfiguration.class); child.setParent(this.context); child.refresh(); assertThat(child.containsBean("baz")).isTrue(); assertThat(child.getBean("baz")).isEqualTo("foo"); child.close(); } @Test public void singleCandidateInAncestorsOneCandidateInGrandparent() { load(FooConfiguration.class); AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); parent.setParent(this.context); parent.refresh(); AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); child.register(OnBeanSingleCandidateInAncestorsConfiguration.class); child.setParent(parent); child.refresh(); assertThat(child.containsBean("baz")).isTrue(); assertThat(child.getBean("baz")).isEqualTo("foo"); child.close(); parent.close(); } @Test public void singleCandidateMultipleCandidates() { load(FooConfiguration.class, BarConfiguration.class, OnBeanSingleCandidateConfiguration.class); assertThat(this.context.containsBean("baz")).isFalse(); } @Test public void singleCandidateMultipleCandidatesOnePrimary() { load(FooPrimaryConfiguration.class, BarConfiguration.class, OnBeanSingleCandidateConfiguration.class); assertThat(this.context.containsBean("baz")).isTrue(); assertThat(this.context.getBean("baz")).isEqualTo("foo"); } @Test public void singleCandidateMultipleCandidatesMultiplePrimary() { load(FooPrimaryConfiguration.class, BarPrimaryConfiguration.class, OnBeanSingleCandidateConfiguration.class); assertThat(this.context.containsBean("baz")).isFalse(); } @Test public void invalidAnnotationTwoTypes() { this.thrown.expect(IllegalStateException.class); this.thrown.expectCause(isA(IllegalArgumentException.class)); this.thrown.expectMessage( OnBeanSingleCandidateTwoTypesConfiguration.class.getName()); load(OnBeanSingleCandidateTwoTypesConfiguration.class); } @Test public void invalidAnnotationNoType() { this.thrown.expect(IllegalStateException.class); this.thrown.expectCause(isA(IllegalArgumentException.class)); this.thrown .expectMessage(OnBeanSingleCandidateNoTypeConfiguration.class.getName()); load(OnBeanSingleCandidateNoTypeConfiguration.class); } @Test public void singleCandidateMultipleCandidatesInContextHierarchy() { load(FooPrimaryConfiguration.class, BarConfiguration.class); AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(); child.setParent(this.context); child.register(OnBeanSingleCandidateConfiguration.class); try { child.refresh(); assertThat(child.containsBean("baz")).isTrue(); assertThat(child.getBean("baz")).isEqualTo("foo"); } finally { child.close(); } } private void load(Class<?>... classes) { if (classes.length > 0) { this.context.register(classes); } this.context.refresh(); } @Configuration @ConditionalOnSingleCandidate(String.class) protected static class OnBeanSingleCandidateConfiguration { @Bean public String baz(String s) { return s; } } @Configuration @ConditionalOnSingleCandidate(value = String.class, search = SearchStrategy.ANCESTORS) protected static class OnBeanSingleCandidateInAncestorsConfiguration { @Bean public String baz(String s) { return s; } } @Configuration @ConditionalOnSingleCandidate(value = String.class, type = "java.lang.String") protected static class OnBeanSingleCandidateTwoTypesConfiguration { } @Configuration @ConditionalOnSingleCandidate protected static class OnBeanSingleCandidateNoTypeConfiguration { } @Configuration protected static class FooConfiguration { @Bean public String foo() { return "foo"; } } @Configuration protected static class FooPrimaryConfiguration { @Bean @Primary public String foo() { return "foo"; } } @Configuration protected static class BarConfiguration { @Bean public String bar() { return "bar"; } } @Configuration protected static class BarPrimaryConfiguration { @Bean @Primary public String bar() { return "bar"; } } }