📌 어떤 객체를 Mock 객체로 선언하는 방법
1️⃣ mock()PostRepository postRepository = mock(PostRepository.class);
2️⃣ @Mock@Mock
private PostRepository postRespository;
+ @Mock을 쓰려면 테스트 클래스 위에 @ExtendWith(MockitoExtension.class)를 붙여줘야 함
①과 ②는 내부적으로 동일하게 동작함. 무엇을 쓰는지는 방법의 차이
3️⃣ @MockBean@MockBean
private PostRepository postRespository;
스프링 부트 테스트에서 제공하는 어노테이션
스프링 컨텍스트에 Mock 객체를 등록하고,
스프링 컨텍스트에 의해 @Autowired가 동작할 때 등록된 mock객체를 사용할 수 있도록 동작함
📌 @InjectMocks
해당 클래스의 Mock 객체들을 감지하고,
해당 클래스의 객체를 만들 때 필요한 의존성에 맞는 Mock 객체를 주입
@Mock
private AccountRepository accountRepository;
@InjectMocks
private AccountService accountService;
// => AccountService 객체를 만들 때 필요한 의존성을 감지하고, 해당하는 목객체인 accountRepository를 주입
📌 @Mock vs. @MockBean
@Mock | @MockBean | |
대상 테스트 | 단위 테스트 | 스프링 컨테이너가 필요한 테스트 |
의존성 주입 | @InjectMocks | @Autowired |
관례적 쓰임 | 서비스 테스트에서 레포지토리를 모킹 | 컨트롤러 테스트에서 서비스를 모킹 |
스프링 컨테이너에 빈을 등록해야하는 테스트에서는 MockBean을,
단위 테스트를 할 때에는 Mock을 사용한다.
@MockBean으로 만든 mock 객체를 주입받고 싶을 때는 @Autowired를
@Mock으로 만든 mock 객체를 주입받고 싶을 때는 @InjectMocks를 사용한다.
관례적으로 서비스 테스트에서 레포지토리를 모킹해올때 @Mock 을
빈 주입을 요구하는 컨트롤러 테스트에서는 @MockBean을 사용한다.
※ MockBean으로 스프링 컨텍스트에 빈으로 등록한 mock 객체는 InjectMocks에 의해 주입될 수 없다! => 에러 발생함
📌 컨트롤러 테스트
WebMvcTest는 스프링 컨테이너에 빈을 등록하여 테스트하므로 @MockBean을 사용해야 함
@WebMvcTest(AccountController.class)
class AccountControllerTest {
// mock 객체를 스프링 컨테이너에 등록
@MockBean
private AccountService accountService;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
(중략)
}
📌 서비스 테스트
서비스 테스트는 스프링 컨테이너 없이 단위테스트가 가능하므로 @Mock을 사용해야 함
@ExtendWith(MockitoExtension.class)
public class FarmingHolidayServiceTest {
@InjectMocks
private FarmingHolidayService sut;
@Mock
private FarmingHolidayRepository farmingHolidayRepository;
(중략)
}
'Spring Boot' 카테고리의 다른 글
[SpringBoot] 연관관계의 주인이 필요한 이유 (0) | 2023.10.01 |
---|---|
[SpringBoot] 테스트 코드 가독성 높이기 - BDDMockito, assertj (0) | 2023.09.29 |
스프링 시큐리티를 이용한 로그인 (0) | 2023.09.03 |
스프링 시큐리티를 이용한 회원가입 (0) | 2023.09.02 |
트랜잭션의 개념과 @Transacional 어노테이션 (0) | 2023.08.11 |