Home / Class/ NoUniqueBeanDefinitionFailureAnalyzerTests Class — spring-boot Architecture

NoUniqueBeanDefinitionFailureAnalyzerTests Class — spring-boot Architecture

Architecture documentation for the NoUniqueBeanDefinitionFailureAnalyzerTests class in NoUniqueBeanDefinitionFailureAnalyzerTests.java from the spring-boot codebase.

Entity Profile

Relationship Graph

Source Code

core/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoUniqueBeanDefinitionFailureAnalyzerTests.java lines 43–249

@WithResource(name = "producer.xml",
		content = """
				<?xml version="1.0" encoding="UTF-8"?>
				<beans xmlns="http://www.springframework.org/schema/beans"
					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
					xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

					<bean class="org.springframework.boot.diagnostics.analyzer.nounique.TestBean" name="xmlTestBean"/>

				</beans>
				""")
class NoUniqueBeanDefinitionFailureAnalyzerTests {

	private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

	private final NoUniqueBeanDefinitionFailureAnalyzer analyzer = new NoUniqueBeanDefinitionFailureAnalyzer(
			this.context.getBeanFactory());

	@Test
	void failureAnalysisForFieldConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(FieldConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith(
				"Field testBean in " + FieldConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisForMethodConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(MethodConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith("Parameter 0 of method consumer in "
				+ MethodConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisForConstructorConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(ConstructorConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith("Parameter 0 of constructor in "
				+ ConstructorConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisForObjectProviderMethodConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(ObjectProviderMethodConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith("Method consumer in "
				+ ObjectProviderMethodConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	@WithResource(name = "consumer.xml",
			content = """
					<?xml version="1.0" encoding="UTF-8"?>
					<beans xmlns="http://www.springframework.org/schema/beans"
						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
						xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

						<bean class="org.springframework.boot.diagnostics.analyzer.nounique.TestBeanConsumer"/>

					</beans>
					""")
	void failureAnalysisForXmlConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(XmlConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith("Parameter 0 of constructor in "
				+ TestBeanConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisForObjectProviderConstructorConsumer() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(ObjectProviderConstructorConsumer.class));
		assertThat(failureAnalysis.getDescription()).startsWith("Constructor in "
				+ ObjectProviderConstructorConsumer.class.getName() + " required a single bean, but 6 were found:");
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisIncludesPossiblyMissingParameterNames() {
		FailureAnalysis failureAnalysis = analyzeFailure(createFailure(MethodConsumer.class));
		assertThat(failureAnalysis.getDescription()).contains(MissingParameterNamesFailureAnalyzer.POSSIBILITY);
		assertThat(failureAnalysis.getAction()).contains(MissingParameterNamesFailureAnalyzer.ACTION);
		assertFoundBeans(failureAnalysis);
	}

	@Test
	void failureAnalysisWithoutInjectionPoints() {
		this.context.registerBean("beanOne", TestBean.class);
		this.context.register(DuplicateBeansProducer.class);
		this.context.refresh();
		FailureAnalysis failureAnalysis = analyzeFailure(new NoUniqueBeanDefinitionException(TestBean.class, 3,
				"no TestBeanProvider specified and expected single matching TestBean but found 3: beanOne,beanTwo,xmlBean"));
		assertThat(failureAnalysis.getDescription())
			.startsWith("A component required a single bean, but 3 were found:");
		assertThat(failureAnalysis.getDescription()).contains("beanOne: defined in unknown location");
		assertThat(failureAnalysis.getDescription())
			.contains("beanTwo: defined by method 'beanTwo' in " + DuplicateBeansProducer.class.getName());
		assertThat(failureAnalysis.getDescription()).contains("xmlBean: a programmatically registered singleton");
	}

	private BeanCreationException createFailure(Class<?> consumer) {
		this.context.registerBean("beanOne", TestBean.class);
		this.context.register(DuplicateBeansProducer.class, consumer);
		this.context.setParent(new AnnotationConfigApplicationContext(ParentProducer.class));
		try {
			this.context.refresh();
			throw new AssertionError("Should not be reached");
		}
		catch (BeanCreationException ex) {
			return ex;
		}
	}

	private FailureAnalysis analyzeFailure(Exception failure) {
		FailureAnalysis analyze = this.analyzer.analyze(failure);
		assertThat(analyze).isNotNull();
		return analyze;
	}

	private void assertFoundBeans(FailureAnalysis analysis) {
		assertThat(analysis.getDescription()).contains("beanOne: defined in unknown location");
		assertThat(analysis.getDescription())
			.contains("beanTwo: defined by method 'beanTwo' in " + DuplicateBeansProducer.class.getName());
		assertThat(analysis.getDescription())
			.contains("beanThree: defined by method 'beanThree' in " + ParentProducer.class.getName());
		assertThat(analysis.getDescription()).contains("barTestBean");
		assertThat(analysis.getDescription()).contains("fooTestBean");
		assertThat(analysis.getDescription()).contains("xmlTestBean");
	}

	@Configuration(proxyBeanMethods = false)
	@ComponentScan(basePackageClasses = TestBean.class)
	@ImportResource("classpath:producer.xml")
	static class DuplicateBeansProducer {

		@Bean
		TestBean beanTwo() {
			return new TestBean();
		}

	}

	@Configuration(proxyBeanMethods = false)
	static class ParentProducer {

		@Bean
		TestBean beanThree() {
			return new TestBean();
		}

	}

	@Configuration(proxyBeanMethods = false)
	static class FieldConsumer {

		@SuppressWarnings("unused")
		@Autowired
		private TestBean testBean;

	}

	@Configuration(proxyBeanMethods = false)
	static class ObjectProviderConstructorConsumer {

		ObjectProviderConstructorConsumer(ObjectProvider<TestBean> objectProvider) {
			objectProvider.getIfAvailable();
		}

	}

	@Configuration(proxyBeanMethods = false)
	static class ConstructorConsumer {

		ConstructorConsumer(TestBean testBean) {

		}

	}

	@Configuration(proxyBeanMethods = false)
	static class MethodConsumer {

		@Bean
		String consumer(TestBean testBean) {
			return "foo";
		}

	}

	@Configuration(proxyBeanMethods = false)
	static class ObjectProviderMethodConsumer {

		@Bean
		String consumer(ObjectProvider<TestBean> testBeanProvider) {
			testBeanProvider.getIfAvailable();
			return "foo";
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ImportResource("classpath:consumer.xml")
	static class XmlConsumer {

	}

}

Domain

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free