참고하면 좋은 글
https://www.java67.com/2023/04/difference-between-mockitomock-mock-and.html
@Mock
은 스프링 컨테이너를 실제로 사용하지 않을 때 사용하는 어노테이션이다.
즉, 다시 말하면 Unit test에서 잘 쓰인다고 할 수 있겠다.
@MockBean
은 스프링 컨테이너내의 Bean을 모킹할 때 사용한다.
즉, @SpringBootTest
(통합테스트) 에서 사용하는 어노테이션이다.
한가지 상황을 가정해보자.
다음은 맞는 코드일까?
(세가지 객체 모두 컨테이너에 등록된 상황임을 가정)
@SpringBootTest
class MemberIntegrationTest {
// 인증 메일 관련 주입
@Autowired
MailService mailService;
@Mock
JavaMailSender mailSender;
@Autowired
AuthCodeRepository authCodeRepository;
//생략 ~~
}
이것은 틀렸다. @SpringBootTest
로 실제 스프링컨테이너를 띄워서 하는 통합테스트의 상황이다. 이 때, @Mock 을 사용해서 모킹을 한다고 해도, 실제로 효과는 없다.
별개로, 부연설명하자면 @Autowired는 당연히 해당 테스트에서 사용할 객체이므로 Field Injection으로 주입시켰다. (테스트 환경이어서 필드주입이 용이한 것이지, 실제 어플리케이션 레벨에서는 사용하지 말자. 테스트도 어렵고.. 의존관계파악하는 것도 어렵고..)
@SpringBootTest
class MemberIntegrationTest {
// 인증 메일 관련 주입
@Autowired
MailService mailService;
@MockBean
JavaMailSender mailSender;
@Autowired
AuthCodeRepository authCodeRepository;
//생략 ~~
}
다음처럼 바꾸어 보자.
이렇게 하면, 실제로 SMTP프로토콜을 사용해 메일을 보내는 것을 mocking하여 테스트해볼 수 있다.