[Spring] 스프링 @MockBean, @SpyBean

2023. 3. 12. 13:56·스터디/Spring
728x90

배경

스프링과 Junit을 이용해서 테스트 코드를 작성하다 보면 테스트 환경(database, api)을 구현하는 코드까지 작성해야 하고 실제 테스트할 코드보다 환경을 구현하는 코드가 훨씬 더 복잡해지게 됩니다.

이런 문제 영역을 해결하기 위해서 테스트 더블 이라는 것이 나왔고 Java진영에서는 대표적으로 Mockito가 있습니다.

Mockito를 사용하다보면 아래 어노테이션을 자주 접하게됩니다.

 

 

@Mock
@MockBean
@Spy
@SpyBean
@InjectMocks

 

SpringBoot 1.4에서 2개의 테스트 어노테이션 @MockBean, @SpyBean 이 추가되었습니다.

 

두 어노테이션 모두 spring-boot-test에서 제공하는 어노테이션입니다.

 

Spring 에서는 보통 객체생성시 직접 생성하지 않고 Dependency Injection(DI)을 통해 프레임워크에 위임하여 생성하기 때문에 직접적으로 Mocking 테스트환경을 만드는것이 쉽지 않습니다.

 

이러한 어려움을 도와주는것이 바로 @MockBean과 @SpyBean입니다.

기본적인 개념은 조금 다르나 사용법은 @MockBean과 @SpyBean은 동일합니다.

 

@MockBean

@Mock 과 비슷한 @MockBean이라는 어노테이션이 있습니다. 이름이 비슷한것처럼 실제로도 비슷하게 동작합니다.

하지만 @Mockbean은 경로(org.springframework.boot.test.mock.mockito.MockBean)를 봐도 알 수 있듯이 @Mock과는 다르게 spring 영역에 있는 어노테이션이라는 것을 알 수 있습니다.

@Mock과 달리 spring-boot-test에서 제공하는 어노테이션이고 Spring이 관리하는 bean들 중에서 하나 이상을 mock 객체로 사용하고 싶을 때 사용합니다.

@MockBean은 스프링 컨텍스트에 mock객체를 등록하게 되고 스프링 컨텍스트에 의해 @Autowired가 동작할 때 등록된 mock객체를 사용할 수 있도록 동작합니다.

@MockBean은 given에서 선언한 코드 외에는 전부 사용할 수 없습니다.

 

@Mock과 @MockBean의 차이가 헷갈릴 수 있는데요 정리하자면 아래와 같습니다.

Mock 종류의존성 주입 Target

Mock 종류 의존성 주입 Target
@Mock @InjectMocks
@MockBean @SpringBootTest

- @Mock은 @InjectMocks에 대해서만 해당 클래스안에서 정의된 객체를 찾아서 의존성을 해결합니다.

- @MockBean은 mock 객체를 스프링 컨텍스트에 등록하는 것이기 때문에 @SpringBootTest를 통해서 Autowired에 의존성이 주입되게 됩니다.

 

@SpyBean

가짜 객체를 만들어서 stub을 해주는 @MockBean과 달리, @SpyBean은 given에서 stub한 메서드 외에는 그 객체의 실제 메서드를 사용할 수 있습니다.

(*stub: 기대 행위를 작성하는 것)

 

@Spybean은 given에서 선언한 코드 외에는 전부 실제 객체의 것을 사용합니다.

마치 실제 객체의 메서드들 중에서 우리가 지정한 특정 메서드만 의도대로 작동되게 하는 것이 그 객체에 스파이를 하나 심어둔 것 같다고 생각하면 이해하기 쉽습니다.

특정 객체의 일부 메서드만 stub하고, 나머지는 실제 메서드를 사용하고 싶을 때 @SpyBean을 사용합니다.

 

@SpyBean은 실제 구현된 객체를 감싸는 프록시 형태이기 때문에 스프링 컨텍스트에 실제 구현체가 등록되어있어야 합니다.

 

출처

https://github.com/mockito/mockito/wiki/Mockito-features-in-Korean

https://jojoldu.tistory.com/226

728x90

'스터디 > Spring' 카테고리의 다른 글

[Springboot] @Scheduled cron 사용하는 방법  (0) 2023.08.12
[Spring] Spring 프로젝트에서 리소스 파일 읽기 (Java8)  (0) 2023.08.11
[Spring] 스프링 캐시 알아보기 (@Cacheable, @CachePut, @CacheEvict)  (1) 2023.03.12
[Spring] Filter와 Interceptor 의미와 차이  (0) 2022.10.06
[Spring] @ResponseBody와 @ModelAttribute 차이점  (0) 2021.08.17
'스터디/Spring' 카테고리의 다른 글
  • [Springboot] @Scheduled cron 사용하는 방법
  • [Spring] Spring 프로젝트에서 리소스 파일 읽기 (Java8)
  • [Spring] 스프링 캐시 알아보기 (@Cacheable, @CachePut, @CacheEvict)
  • [Spring] Filter와 Interceptor 의미와 차이
zoodi
zoodi
IT/개발 관련 지식을 기록하는 블로그입니다.
  • zoodi
    오늘의 기록
    zoodi
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 후기
        • 컨퍼런스
        • 일상리뷰
      • 금융경제
        • 뉴스
        • 금융IT용어
        • 경제 및 부동산
      • 코딩 테스트
      • 스터디
        • JAVA
        • Kotlin
        • Spring
        • React, Nextjs
        • 인공지능 AI
        • Cloud & k8s
        • Kafka
        • Database
        • Network
        • Algorithm
        • Hadoop
        • LINUX
        • R Programming
        • 기타 (소공, 보안)
      • 도서
      • 기타
  • 블로그 메뉴

    • 홈
    • 스터디
    • 금융경제
    • 후기
    • 기타
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    금융용어
    리트코드
    알고리즘
    CodingTest
    db
    쿠버네티스
    LeetCode
    MySQL
    네트워크
    스프링
    프로그래머스
    자바
    코테공부
    스프링부트
    코딜리티
    카카오코테
    코테
    codility
    코딩
    Kotlin
    자료구조
    pythoncodingtest
    java
    kafka
    C++
    springboot
    코딩테스트
    Python
    Spring
    이분탐색
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
zoodi
[Spring] 스프링 @MockBean, @SpyBean
상단으로

티스토리툴바