Java/Test

MockMvc로 API 슬라이스 테스트 하기

keep it simple 2023. 8. 9. 03:19

개념 알아보기

슬라이스 테스트란? 

  • 특정 계층 테스트를 말한다. @SpringBootTest를 사용하여 통합테스트를 하는것보다 슬라이스 테스트를 하면 더 작은 단위로 쪼개어 테스트하기 때문에 테스트 시간이 짧고, 관련 없는 빈들을 로드하지 않아 통합테스트보다 가볍고 빠른 테스트가 가능하다.
  • @WebMvcTest:
    • 웹 계층의 컨트롤러(Controller) 테스트를 위한 슬라이스 테스트입니다. @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver 관련 bean들이 로드됩니다.
  • @DataJpaTest:
    • JPA관련 테스트를 위한 슬라이스 테스트입니다. 테스트가 in-memory 데이터베이스를 사용하고 transactional이 적용되며 테스트가 끝날때 rollback됩니다
  • @RestClientTest:
    • REST 클라이언트(외부 API - infra계층) 테스트를 위한 슬라이스 테스트입니다.
  • @MockBean:
    • 서비스(Service) 테스트를 위한 슬라이스 테스트로, 특정 서비스를 실제 구현 대신 목(Mock) 객체로 대체합니다.

예제를 통해 알아보기

새로 전학 온 학생을 시스템에 등록하는 API 이다.

 

Controller

@RestController
@RequestMapping("api/v1/students")
@RequiredArgsConstructor
public class StudentController {
    private final StudentService studentService;

    @PostMapping("/new")
    public StudentResponse createStudent(@RequestBody StudentCreateRequest request) {
        return studentService.createStudent(request);
    }

}

Test Code

@WebMvcTest(controllers = StudentController.class)
class ProductControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private StudentService studentService;


    @Test
    @DisplayName("신규 학생을 등록한다.")
    void createStudent() throws Exception {
        // given
        StudentCreateRequest request = StudentCreateRequest.builder()
                .grade(StudentGrade.JUNIOR)
                .name("홍길동")
                .age(15)
                .build();

        // when // then
        mockMvc.perform(MockMvcRequestBuilders.post("/api/v1/students/new")
                        .content(objectMapper.writeValueAsString(request))
                        .contentType(MediaType.APPLICATION_JSON)
                )
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk());
    }
}

  • @WebMvcTest(controllers = 테스트할 컨트롤러 클래스 명시)

mockMvc.perform() 함수를 사용하여 테스트한다.

  • Controller에서 StudentService가 final이기때문에 @MockBean을 사용하여 서비스를 mocking해준다.
  • MockMvcRequestBuilders를 사용해 테스트할 api 엔드포인트를 명시한다.
  • content에 objectMapper 를 통해 requestbody를 직렬한 데이터를 넣어준다.
  • contentType에 json 데이터이기때문에 MediaType.APPLICATION_JSON을 명시해준다.
  • MockMvcResultHandlers.print()는 콘솔에 더 자세한 로그를 보기위해 사용한다.
  • MockMvcResultMAtchers.status().isOk()를 통해 http 상태값이 200이 떨어지는지 테스트한다.