본문 바로가기

Study

[내일배움캠프 TIL] 32일차 - 단위테스트와 Mock Mvc의 이해

728x90
반응형

단위테스트 관련 계속 헷깔렸던 부분을 정리해봤습니다.

1. "내가 정한 답(Mock)을 왜 테스트하는가?"

컨트롤러 단위 테스트의 목적은 '데이터의 정답 여부'가 아니라 'API 계약(Contract)의 이행'이다.

  • 의존성 분리: 서비스나 DB가 고장 나도 컨트롤러 로직만 독립적으로 검증하기 위해 가짜 객체(MockBean)를 사용한다.
  • 검증 핵심: 서비스가 어떤 데이터를 주든, 컨트롤러가 정해진 응답 규격(JSON 포맷, HTTP 상태 코드)으로 예쁘게 포장해서 내보내는지를 확인하는 것이 핵심이다.

=> 단위 테스트 핵심은 그 함수의 기능만 동작 잘하는지 보는것이라, 나머지 연결된 것들은 가짜로 처리한다.

2. MockMvc와 @MockBean의 마법

  • MockMvc: 실제 서버를 띄우지 않고도 요청을 보내고 응답을 검증하는 가짜 클라이언트.
  • @MockBean: 스프링 보관함(Context)에 있는 진짜 서비스를 가짜(Mock) 서비스로 갈아끼워 주는 역할.
  • 연결 고리: MockMvc가 요청을 날리면 DispatcherServlet이 이를 받아, 이미 가짜 서비스가 꽂혀 있는 컨트롤러를 호출하여 전체 흐름이 완성된다.

3. 코드 요약 및 검증 포인트

 

@Test
@WithMockUser
@DisplayName("API 응답 규격 검증: POST /api/v1/companies")
void createCompanyApiResponseFormatTest() throws Exception {
    // 1. Given: 서비스가 돌려줄 가짜 응답(답정너) 설정
    when(companyService.createCompany(any())).thenReturn(responseDto);

    // 2. When: MockMvc로 가짜 요청 전송
    mockMvc.perform(post("/api/v1/companies")
                    .with(csrf())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(request)))
    // 3. Then: 데이터 내용보다 '응답의 모양'을 검증
            .andExpect(status().isCreated()) // 201 응답이 오는가?
            .andExpect(jsonPath("$.status").value(201)) // 공통 규격 status가 있는가?
            .andExpect(jsonPath("$.data.companyName").value("Test Company")); // 데이터가 규격에 맞게 매핑됐나?
}

4. 결론

단위 테스트는 '기사님(컨트롤러)이 택배 박스(응답 규격)를 제대로 포장했는가'를 보는 과정이다. DB까지 연결하는 통합 테스트와 달리, 매우 빠르고 프론트엔드와의 협업 규칙(API 명세)을 지키는 데 필수적이다.

반응형