[개발일지] 230509 @Mock, @MockBean, @InjectMocks의 관계

오늘은 회사에서 테스트 코드 작성 중 기존 테스트 코드를 살펴보다 어떤 곳은 @InjectMocks를 사용했고 어떤 곳은 @MockBean을 사용하고 있길래 어떤 차이가 있는지 궁금해서 알아봤다. 

 

오늘 새로 배운 내용

@Mock, @InjectMocks, @MockBean의 관계

@Mock은 Mock(가짜) 객체를 생성하고, @InjectMocks는 클래스의 인스턴스를 생성한 후 @Mock 어노테이션으로 생성된 Mock 객체를 이 인스턴스에 주입한다.

@MockBean은 스프링 컨텍스트에 Mock 객체를 등록해 @SpringBootTest와 함께 사용할 때 @Autowired가 붙은 필드에 자동으로 의존성을 주입한다.

 

  1. @Mock: @Mock 어노테이션은 Mock(가짜) 객체를 생성한다. Mock 객체는 실제 객체를 대신 동작하는 가짜 객체로, 테스트 시에 원하는 결과를 반환하도록 설정할 수 있다. 
  2. @InjectMocks: 이 어노테이션은 테스트 대상 클래스의 인스턴스를 생성하고, 해당 클래스가 의존하는 객체들을 자동으로 주입해 준다. 이를 통해 테스트 대상 객체가 필요로 하는 의존성을 쉽게 해결할 수 있다. @InjectMocks 어노테이션은 테스트 대상 클래스에 적용되며, 해당 클래스의 인스턴스를 생성하고 필요한 의존성을 자동으로 주입해 준다.
  3. @MockBean: @MockBean은 해당 어노테이션이 붙은 Mock 객체를 스프링 컨텍스트에 등록하여 @SpringBootTest를 통해서 @Autowired가 붙은 필드에 자동으로 의존성 주입을 해준다. 이를 통해 실제로 의존하고 있는 의존관계 대신 Mock객체를 주입해 테스트할 때 예상 동작을 수행할 수 있게 한다.

 

@MockBean과 @InjectMocks의 목적과 사용 방법

@MockBean

  • Spring 테스트에서 사용되며, 스프링 컨텍스트에 Mock(가짜) 객체를 등록
  • 스프링 애플리케이션 컨텍스트에 등록되므로 실제 Bean과 동일한 방식으로 주입
  • @Autowired 어노테이션을 통해 Mock 객체를 주입받을 수 있다.
  • 외부 의존성을 가지는 클래스에 대해 Mock 객체를 주입하여 통합 테스트를 수행하는 데 사용된다.

 

@InjectMocks

  • Mockito 프레임워크에서 사용되며, 클래스의 인스턴스를 생성하고 Mock 객체를 주입한다.
  • 클래스의 인스턴스를 직접 생성하므로 스프링 컨텍스트와는 무관하며, Mock 객체는 주입될 클래스의 필드에 @Mock 어노테이션을 사용하여 정의한다.
  • 클래스의 생성자 또는 setter 메서드를 통해 Mock 객체가 주입
  • 주로 단위 테스트에서 사용되며, 클래스의 인스턴스를 생성하고 Mock 객체를 주입하여 테스트를 수행하는 데 사용된다.

 

결국 둘 중 어떤 것을 사용해야 할지는 테스트의 목적에 따라 달라진다.

  • @MockBean은 스프링 애플리케이션 컨텍스트와 통합 테스트를 할 때 외부 의존성을 가지는 클래스의 테스트를 할 때 사용
  • @InjectMocks는 단위 테스트를 할 때 특정 클래스의 인스턴스를 생성하고 Mock 객체를 주입하여 테스트를 할 때 사용

 

결론

일반적으로 특정 메서드의 동작을 테스트(단위 테스트)할 때는 @InjectMocks를 사용하는 것이 적절하고 Controller나 Service 단 같은 클래스단(통합 테스트)을 테스트할 때는 @MockBean을 사용하는 것이 적절하다.