MockMvc?
- MockMvc란
- MVC에 관련된 Mock 가짜 객체
- 웹 어플리케이션을 서버에 배포하지않고, 테스트용 MVC 환경을 만들어서 요청 및 전송, 응답 기능을 제공해주는 객체
- MockMvc를 통해 @Autowired로 주입받아서 사용 가능
@SpringBootTest
- SpringApplication을 통해서 테스트에서 사용할 ApplicationContext를 쉽게 생성할 수 있습니다.
- 그러므로, @SpringBootAplication이 붙은 어노테이션을 찾아 하위의 모든 빈들을 scan하기 때문에 애플리케이션에 정의된 모든 빈을 생성하여 ‘실행 시 느려질 수 있으므로, 단위 테스트에서는 적합하지 않다.’
@SpringBootTest
@AutoConfigureMockMvc //SpringBootTest에서는 MockMvc 객체를 사용하려면 해당 어노테이션 선언 필요
class SpringBootTest {
@Autowired
MockMvc mockMvc; // 주입 O
}
@SpringBootTest
@AutoConfigureMockMvc
class SpringBootTest {
@Autowired
MockMvc mockMvc; // 주입 O
@Autowired
UserController userController; // 주입 O
@Autowired
UserRepository userRepository; // 주입 O
@Autowired
UserService userService; // 주입 O
}
@WebMvcTest
- Web Layer 관련 빈들만 등록하므로, @Component로 등록된 리포지토리와 서비스는 주입이 되지 않는다.
- Web Layer = Security, Filter, Interceptor, Handling, Controller
- 그러므로, 이외는 @MockBean 을 통해 주입받아야한다.
- @MockBean = Spring Application Context에 Mock 객체를 빈으로 등록하는데 사용되는 annotation
@WebMvcTest
class SpringBootTest {
@Autowired
MockMvc mockMvc; // 주입 O
@Autowired
UserController userController; // 주입 O
//@Autowired
@MockBean
UserRepository userRepository; // 주입 X
//@Autowired
@MockBean
UserService userService; // 주입 X
}
Java 단위의 Unit Test (단위 테스트)
- JUnit5 : 자바 단위 테스트를 지원하는 ‘테스팅 프레임워크’
- AseertJ : .. ‘라이브러리’
given/when/then 패턴
- given : 어떤 데이터가 준비되었을 때
- when : 어떠한 함수를 실행하면
- then : 어떠한 결과가 나와야한다
Mockito
개발자가 동작을 직접 제어할 수 있는 ‘가짜 객체’를 지원하는 테스트 프레임워크
- Spring은 여러 객체들 간의 의존성이 발생하는데, 이러한 의존성은 단위 테스트 작성을 어렵게 한다.
- 이를 해결하기 위해, 가짜 객체를 주입시키는 Mockito 라이브러리를 활용할 수 있다.
- 가짜 객체에 원하는 결과를 Stub (하향식 테스트) 단위 테스트 가능
- => 가짜 객체를 주입하여 어떤 결과를 반환하라고 준비해야함
- doReturn() : 가짜 객체가 특정한 값을 반환하는 경우
- doNothing() : 가짜 객체가 아무 것도 반환하지 않는 경우 (void)
- doThrow() : 가짜 객체가 예외를 발생시키는 경우
- @Mock : 가짜 객체를 만들어 반환
- @InjectMocks : 가짜 객체를 자동으로 주입시켜주는 어노테이션
- example) @Mock을 통해 가짜 서비스 생성 후, @InjectMocks 를 통해 Controller에 이를 주입할 수 있다.
- SpringBoot 2.2.0부터 공식적으로 JUnit5를 지원함에 따라, 이제부터는 @ExtendedWith(MockitoExtension.class)를 사용해야 결합이 가능하다.
@Transactional
@ExtendWith(MockitoExtension.class)
class ProductServiceTest {
@InjectMocks //@Mock으로 생성된 가짜 객체들을 주입받음 (테스트해야할 서비스)
private ProductService productService;
@Mock
private MemberService memberService;
@Mock
private MemberRepository memberRepository;
@Mock
private ReservationRepository reservationRepository;
@Mock
private ProductRepository productRepository;
@Mock
private SecurityUtil securityUtil;
각 Layer 별 Test 범위
- Controller: @WebMvcTest는 웹 계층을 테스트하며, 유닛 테스트라기보다는 웹 통합 테스트에 가까운 테스트입니다.
- Repository: @DataJpaTest는 JPA 리포지토리와 데이터베이스의 상호작용을 테스트하며, 이는 통합 테스트에 속합니다.
- Service: @ExtendWith(MockitoExtension.class)와 @Mock을 사용하는 서비스 계층 테스트는 유닛 테스트로, 비즈니스 로직만 검증하는 데 중점을 둡니다.
WebMvcTest | SpringBootTest | Junit 단위(클래스/메소드) 테스트 | |
목적 | 웹 계층(Controller)만 테스트 | 전체 애플리케이션(서비스, 리포지토리 등) 통합 테스트 | 단위(클래스/메소드) 테스트 |
테스트 범위 | Controller, 필터 등 웹 관련 구성 요소만 테스트 | 전체 Spring 컨텍스트 로드, 실제 서버 및 DB와 연동 가능 | 특정 클래스나 메소드만 테스트, 외부 의존성 모킹 |
속도 | 빠름, 웹 계층만 로드 | 느림, 전체 애플리케이션 로드 | 매우 빠름, 독립적 테스트 |
주요 사용 목적 | HTTP 요청과 응답 처리 테스트 (컨트롤러 테스트) | 애플리케이션 전체 통합 동작 테스트 (서비스, DB 등) |
특정 비즈니스 로직, 메소드 동작 검증 |
외부 의존성 | 외부 서비스는 @MockBean을 사용하여 모킹 | 실제 DB 및 외부 시스템과 통합될 수 있음 | 외부 의존성은 모킹하여 격리 |
'BACKEND > JAVA & SPRING' 카테고리의 다른 글
업캐스팅, 다운캐스팅에 대해 (3) | 2024.10.30 |
---|---|
벌크연산을 통한 update 성능 개선 시도 그리고 일반 연산과의 비교 (0) | 2024.08.07 |
MultipartFile와 Ajax를 활용한 파일 업로드 (0) | 2024.08.01 |
Transaction의 전파 (feat. REQUIRES_NEW의 문제점) (0) | 2024.07.31 |
[Spring Security + JWT + OAUTH2] 카카오/네이버 외부 로그인 구현 (0) | 2024.04.30 |