서비스 계층 단위 테스트
서비스 계층의 단위 테스트는 이전 포스트를 참고해주세요.
[Spring Boot] Mockito를 사용한 단위 테스트 종속성 제거
원인 서비스 계층의 테스트를 작성하면서 assertJ로 테스트를 작성했다. Service계층은 DAO에 종속되어 메소드를 사용하기 때문에 DAO를 통해서 새로 만들어진 객체를 삭제해주어야 했고 DAO를 통해서
g-db.tistory.com
이번 포스트에서는 MockMvc를 사용하여 컨트롤러 계층의 테스트를 진행하겠다.
MockMvc
MockMvc는 이름 그대로 Mvc를 목킹해주는 객체이다.
Http 요청을 보내 스프링 MVC를 테스트할 수 있다.
기본 설정
@WebMvcTest(AuthController.class)
public class AuthControllerTest {
// http를 테스트하기 위한 객체
private final MockMvc mockMvc;
// AuthController가 의존하고 있는 authService의 역할을 수행한다.
@MockBean
private AuthService authService;
// filter 의존성 주입
@MockBean
private JwtProvider jwtProvider;
@MockBean
: 테스트할 대상인 Controller가 주입받는 Bean을 Mock 객체로 만들어 주입시켜준다.
- 해당 프로젝트에서는 SpringSecurity를 사용하여 JWT 토큰 인증을 채택하여 사용중이다.
- 따라서 Filter에서 의존하고 있는 JwtProvider도 빈으로 주입해주어야 했다.
@WebMvcTest(테스트할 클래스.class)
: 스프링 MVC를 테스트하기 위한 여러 어노테이션이 포함되어 있다. 어노테이션은 다음과 같다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(WebMvcTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(WebMvcTypeExcludeFilter.class)
@AutoConfigureCache
@AutoConfigureWebMvc
@AutoConfigureMockMvc
@ImportAutoConfiguration
public @interface WebMvcTest {
단위 테스트
@Test
@DisplayName("회원가입 테스트")
public void signUpTest() throws Exception {
//given
// refEq를 통해 동등성 비교
given(authService.signup(refEq(user1)))
.willReturn(UserDTO.builder().email(user1.getEmail()).build());
// when
// restAPI 를 테스트하기 위한 객체
mockMvc.perform(post("/auth/signup")
.contentType(MediaType.APPLICATION_JSON)
// post body값 설정 (UserDTO를 json string으로 변환)
.content(new ObjectMapper().writeValueAsString(user1)))
.andExpect(status().isCreated())
// json의 depth가 깊어지면, .을 추가하여 탐색할 수 있음 (ex: $.productId.productIdName)
.andExpect(jsonPath("$.email").value(user1.getEmail()))
.andExpect(jsonPath("$.password").isEmpty())
.andDo(print());
// then
// 해당 메소드가 실행되었는지를 검증할 수 있다. (eq 메소드로 동등성 비교)
verify(authService).signup(refEq(user1));
}
Given-When-Then 패턴을 따라서 구성하였다.
given()
: Mock 객체의 메소드가 지정된 매개변수로 호출되었을 경우 반환하는 리턴값을 지정해준다.
- 여기서 객체를 통해 매개변수를 받는다면 기본적으로 동일성을 비교하기 때문에 똑바로 실행되지 않는다.
- 따라서 refEq()를 통해 동등성 비교로 매개변수를 설정해주었다.
- 리턴값은 서비스 계층에서 반환해주어야 하는 것을 설정해주면된다.
mockMvc.perform()
: 빌더 형태의 메소드로써 HTTP 요청에 대한 테스트를 진행할 수 있다.
- 매개변수로 post(), get(), put()과 같은 HTTP 메소드를 입력받는다.
- json을 body에 넣어주기 위해서는 objectMapper를 사용하여 DTO를 jsonString으로 변환하여 사용해주면 된다. (Gson과 같은 라이브러리 사용 가능)
.andExpect()
: perform() 메소드의 빌더로 구성되며 HTTP 응답에 대한 검증을 진행한다.
status()
: 응답의 상태 코드를 검증한다.jsonPath()
: json 값을 검증한다. (.value, .exists 등의 검증 가능)
.andDo(print())
: 테스트 결과를 출력한다. (Spring MVC의 ModelAndView, FlashMap, ExceptionAdapter 등을 출력)
verify()
: Mockito 프레임 워크의 스태틱 메소드로 given() 메소드에서 정의해주었던 Mock 객체의 행위가 호출되었는지 여부를 검증한다.
결과
mockMvc.perform().andDo(print()) HTTP 결과 출력
'Spring' 카테고리의 다른 글
[Spring JPA] 일대다 연관관계 매핑 (0) | 2024.02.04 |
---|---|
[Spring] ControllerAdvice, RestControllerAdvice를 통한 예외 처리 (0) | 2024.02.02 |
[Spring Test] Mockito when()과 given() 차이 (0) | 2024.01.29 |
[Spring Boot] 스프링 부트 HTTPS 적용 방법 (1) | 2024.01.26 |
[Spring Boot] Interceptor 활용 (1) | 2024.01.25 |