Dev/Spring

[스프링 핵심 원리] Spring Container & Bean

oxdjww 2023. 9. 22. 18:55
728x90
반응형

이전 포스팅 : [스프링 핵심 원리] Spring 적용


Intro

본 카테고리는 Inflearn 김영한 강사님의 스프링 핵심 원리 강의를 수강하며 이해하고 학습한 내용을 정리한 내용으로 구성되어 있다.
본 포스팅에서는 Spring Container에서 Bean이 저장되었는지 확인할 수 있는 Testcode를 작성하는 부분을 다룬다.

Testcode dir


src > test > java > hello > core > beanfind

AnnotationConfigApplicationContext


public class ApplicationContextBasicFindTest {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

ApplicationContextBasifFindTest 내부에 AnnotationConfigApplicationContext형 변수를 하나 생성한다.

저번 포스팅에서 언급했듯이, AnnotationConfigApplicationContext형 인스턴스를 참조하는 객체인 ac스프링 컨테이너라고 할 수 있다.

스프링 컨테이너에 접근할 수 있는 ac를 활용하여 method를 구현하여 여러 test를 실행한다.

findBeanByName


...
// import static 를 통해 가독성 확보
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
...

@Test
@DisplayName("빈 이름으로 조회")
void findBeanByName() {
    MemberService memberService = ac.getBean("memberService", MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}

@Test
@DisplayName("빈 이름으로 조회X")
void findBeanByNameX() {
    assertThrows(NoSuchBeanDefinitionException.class, () -> ac.getBean("xxxxx", MemberService.class));
}

bean의 이름으로 조회한다. bean의 이름이란, @Bean 어노테이션이 붙은 메서드를 의미한다.


메서드의 이름으로 bean이 할당되며, key-value 구조로 bean들을 저장하고 있는 스프링 컨테이너 객체들의 key가 된다.


findBeanByName 함수에서는 memberService라는 이름의 bean을 조회하고, Assertions.classassertThat 메서드를 통해 구현 클래스(MemberServiceImpl.class)의 객체인지 검증하는 testcode를 작성하였다.

등록된 bean 이름이 존재하지 않을 경우, 이를 검증하는 예외 테스트도 구현하였다.

ac.getBean("xxxxx", MemberService.class);
MemberService xxxx = ac.getBean("xxxxx", MemberService.class);

같은 구문이 발생하면, 예외를 발생시키는지에 대해 assertThrows와 java 8부터 적용된 람다를 이용하여 testcode를 작성하였다.

findBeanByType


@Test
@DisplayName("이름 없이 타입으로만 조회")
void findBeanByType() {
    MemberService memberService = ac.getBean(MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}

@Test
@DisplayName("구체 타입으로 조회")

void findBeanByType2() {
    MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}

위에서 테스트했던 것과는 다르게, bean의 이름이 아닌, type으로만 조회해보았다.
type이란 memberService 객체의 type인 memberService.classgetBean 메서드를 사용한다.

마찬가지로 Assertions.classassertThatisInstanceOf 구문을 통해 실제 구현체의 type인 MemberServiceImpl.class의 객체인지도 확인해주었다.

또, 추상 인터페이스인 MemberService로 자료형(type)을 검증하는 것이 아니라, MemberServiceImpl.class 자체를 bean 식별의 기준으로 사용하여 getBean 메서드에 넣어주었다.

물론, 일반적으로 interface 변수명 = new 구체화된클래스() 로 코드를 작성하는 것이 일반적이고, 객체지향의 특성을 잘 반영하기 위해 추상화에 의존하는 것이 더 좋은 코드이지만 실제 testcode를 작성하는 실무에서는 이렇게 사용하는 경우도 있다고 한다.

만약을 대비해 알아두면 된다.

Test Result



감사합니다.

728x90
반응형