배경
스프링과 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
'스터디 > Spring' 카테고리의 다른 글
[Springboot] @Scheduled cron 사용하는 방법 (0) | 2023.08.12 |
---|---|
[Spring] Spring 프로젝트에서 리소스 파일 읽기 (Java8) (0) | 2023.08.11 |
[Spring] 스프링 캐시 알아보기 (@Cacheable, @CachePut, @CacheEvict) (0) | 2023.03.12 |
[Spring] Filter와 Interceptor 의미와 차이 (0) | 2022.10.06 |
[Spring] @ResponseBody와 @ModelAttribute 차이점 (0) | 2021.08.17 |
댓글