우리는 보통 Controller나 Service에서 객체를 호출할 때 @Autowired나 @RequiredArgsConstructor와 같은 방법을 사용하여 의존성을 주입받습니다.
하지만 테스트를 할때도 실제 객체들과 데이터들을 불러온다면 테스트코드를 작성하는 의미가 있을까요?
이럴때 쓰기 좋은게 @Mock입니다.
@Mock은 실제객체를 부르지않고 가짜 객체를 생성할 때 사용을 합니다.
@Mock은 Mockito 라이브러리에서 제공하는 애너테이션으로, 테스트 환경에서 실제 객체 대신 동작을 흉내 낼 수 있는 가짜 객체를 생성합니다. 이를 통해 의존성 주입이 필요한 클래스의 객체를 실제로 생성하거나 호출하지 않고도, 해당 객체의 동작을 제어하거나 검증할 수 있습니다.
@Mock이 테스트환경을 위한 실제 객체를 흉내낼 수 있는 가짜 객체라면 @MockBean은 무엇일까요?
@MockBean은 가짜객체을 빈으로 등록해주는 것이다. 그렇다면 빈으로 등록을 왜하는걸까?
@MockBean을 사용하면 Spring Test 환경에서 실제 빈을 가짜 빈으로 대체할 수 있기 때문에, 다른 컴포넌트와의 상호작용을 테스트할 때 유용합니다
@Spy는 Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체 일부는 실제 객체처럼 동작시키고 일부만 Stubbing할 수 있습니다.
Stub은 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체 그 외에는 응답하지 않습니다.
결국 Stub은 상태 검증을 해줍니다.
@SpyBean은 실제 객체를 사용하는 것처럼 보이지만, 테스트 환경에서 객체의 동작을 제어할 수 있도록 가짜로 "위장"한 객체입니다.
그렇다면 실제 객체를 이용하니 데이터가 진짜로 들어가지는 않을까? 라는 의문이 들 수 있습니다.
하지만 @SpyBean은 실제 객체를 "Spy"하여 사용하지만, 테스트 환경에서는 외부 시스템과의 상호작용을 제어하여 실제 데이터베이스나 외부 시스템에 영향을 주지 않도록 할 수 있습니다.
@InjectMocks는 @Mock 또는 @Spy로 생성된 가짜(Mock) 객체들을 테스트 대상 클래스의 의존성으로 자동으로 주입해주는 애너테이션입니다. 이를 통해 테스트할 클래스에서 의존성 객체를 실제 객체 대신 가짜 객체로 쉽게 주입할 수 있습니다.