package dh0023.springcore.beanfind;
import dh0023.springcore.discount.service.DiscountPolicy;
import dh0023.springcore.discount.service.FixDiscountPolicy;
import dh0023.springcore.discount.service.RateDiscountPolicy;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
public class ApplicationContextExtendsFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
@DisplayName("부모 타입으로 조회시, 자식이 둘 이상 있으면, 중복 오류 발생")
void findBeanByParentTypeDuplicate() {
// org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'dh0023.springcore.discount.service.DiscountPolicy' available: expected single matching bean but found 2: rateDiscountPolicy,fixDiscountPolicy
// DiscountPolicy discountPolicy = ac.getBean(DiscountPolicy.class);
assertThrows(NoUniqueBeanDefinitionException.class, () -> ac.getBean(DiscountPolicy.class));
@DisplayName("부모 타입으로 조회시, 자식이 둘 이상 있으면, 빈 이름을 지정하면 된다.")
void findBeanByParentTypeBeanName() {
DiscountPolicy discountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
assertThat(discountPolicy).isInstanceOf(RateDiscountPolicy.class);
@DisplayName("특정 하위 타입으로 조회")
void findBeanBySubType() {
RateDiscountPolicy rateDiscountPolicy = ac.getBean(RateDiscountPolicy.class);
assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
@DisplayName("부모 타입으로 전체 조회")
void findAllBeansByParentType() {
Map<String, DiscountPolicy> beansOfType = ac.getBeansOfType(DiscountPolicy.class);
assertThat(beansOfType.size()).isEqualTo(2);
@DisplayName("부모 타입으로 전체 조회 - Object")
void findAllBeansByObjectType() {
Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
for (String key : beansOfType.keySet()) {
System.out.println("key = " + key + " object " + beansOfType.get(key));
static class TestConfig {
* @return DiscountPolicy : 역할과 구현을 구분하기 위해서
public DiscountPolicy rateDiscountPolicy() {
return new RateDiscountPolicy();
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();