Skip to content

단위테스트 ‐ Controller 계층

Jae-Hyeon Kim edited this page Jun 13, 2024 · 2 revisions

컨트롤러 계층은 사용자의 데이터를 서비스 계층으로 넘기는 역할을 한다.

이 계층에서 검사할 것은 전달된 데이터에 대한 검증, Service 계층으로 넘기는 데이터에 대한 검증이다.

여기서도 마찬가지로, Controller 의 동작에 대한 단위테스트이므로, Service 계층은 목 객체를 만들어 진행한다.

MockMvc

Controller 는 사용자로부터 입력을 받는 과정이 필요하다.

하지만 사용자의 입력을 받기 위해서는 스프링 프레임워크에 내장된 톰캣 서버를 실행시켜야 하고 이러한 과정이 추가되면 테스트에 상당한 시간이 소요되게 된다.

MockMvc 는 서버를 띄우지 않고도 요청을 테스트할 수 있는 도구다. HTTP 요청을 모킹하고, 컨트롤러의 응답을 모킹해 이를 검증할 수 있다.

예제코드

예제코드
@ExtendWith(MockitoExtension.class)
class UserControllerTest {

  @InjectMocks
  private UserController userController;

  @Mock
  private UserService userService;

  @Captor
  private ArgumentCaptor<JoinDto> joinDtoCapture;

  private MockMvc mockMvc;

  @BeforeEach
  public void beforeEach() {
    mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
  }

  @Test
  public void 회원입() throws Exception {
    // given
    String username = "test";
    String email = "email@email.com";
    String password = "test";
    UserType userType = UserType.USER;

    JSONObject requestBody = new JSONObject();
    requestBody.put("username", username);
    requestBody.put("email", email);
    requestBody.put("password", password);
    requestBody.put("userType", "USER");

    JoinDto joinDto = DtoBuilder.getJoinDto(username, email, password, userType);
    // when
    ResultActions perform = mockMvc.perform(
        MockMvcRequestBuilders.post("/api/join")
            .contentType(MediaType.APPLICATION_JSON)
            .content(requestBody.toString()));

    // then
    verify(userService, times(1)).joinUser(joinDtoCapture.capture());
    JoinDto capturedJoinDto = joinDtoCapture.getValue();
    perform.andExpect(MockMvcResultMatchers.status().isNoContent());
    assertThat(capturedJoinDto).isEqualTo(joinDto);
  }
}

Controller 에서 검증할 내용은 사용자의 RequestBody 로 넘어온 JSON 문자열을 파싱해 DTO로 만들고 이 DTO를 Service 계층으로 넘기는 과정이다.

예제 코드에서 알 수 있듯, userService 를 목으로 만들고, 필요할때 동작을 정의해 사용한다.

userService.joinUser 의 호출 회수를 검증하고, 인수를 캡쳐해 검증을 시도한다.

또한 사용자의 요청과, 그에대한 응답을 테스트하기 위해 MockMvc 를 사용해 요청과 응답을 테스트한다.

2024.06.14 추가

기본 MockMvc만 사용하기에는 시큐리티 기능을 사용할 수 없는 문제가 있었다.

이 문제 해결은 https://github.com/f-lab-edu/jshop/wiki/%5B트러블슈팅%5D-@Controller-레이어-테스트-SecurityContext

Clone this wiki locally