본문 바로가기
PlayGround/마실가실 리팩토링

[1년 후 마실가실] PostMan과 Controller Test Code

by HJ0216 2024. 9. 19.

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.

 

사실 테스트 코드 작성 관련해서는 이전에 한 번 글을 쓴 적이 있습니다.

 

그 때는 Service 코드를 검증하였습니다.

Spring 강의를 들을 때, 테스트 코드를 Service 단에서 작성했기에 해당 코드를 응용해가며 리팩토링할 때 테스트 코드를 만들어갈 수 있었습니다.

 

하지만, Controller는 테스트 코드를 작성해본 적이 없습니다..?

 

그래서 PostMan을 사용하다가, Postman에서 검증이 다 끝났기에 Test Code를 공부하면서 작성해보면 좋을 것 같아 글을 작성하게 되었습니다.

 

Contoller 테스트 코드를 작성하며 쓰는, PostMan과 헤어질 결심..!

 

https://hj0216.tistory.com/933

 

[1년 후 마실가실] Test Code 작성

1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다. Test Code가 없던 1년 전 마실가실, 리팩토링을 하면서 Test Code가 생겼습니다.예상 동작과 실제 동작을 비교하여 빠르

hj0216.tistory.com

 

UserControllerTest.java
@SpringBootTest
@AutoConfigureMockMvc(addFilters = false)
class UserControllerTest {
    @Autowired MockMvc mockMvc;
    @Autowired ObjectMapper objectMapper;
    @MockBean UserService userService;

    @Test
    @DisplayName("Controller: 회원 가입 성공")
    void createSuccess() throws Exception {
        // given
        SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
                .status("M")
                .email("new@email.com")
                .phone("01023698741")
                .nickname("name")
                .password("newnew123!")
                .confirmPassword("newnew123!")
                .build();

        // when // then
        mockMvc.perform(post("/api/v2/users/new")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(signUpDto)))
                .andExpect(status().isCreated());

        // 회원 생성 메소드가 호출되었는지 확인
        verify(userService).create(refEq(signUpDto));
    }

    @Test
    @DisplayName("Controller: 회원 가입 실패, 중복된 이메일")
    void createFailDuplicateEmail() throws Exception {
        // given
        SignUpRequestDTO signUpDto = SignUpRequestDTO.builder()
                .status("M")
                .email("temp@email.com")
                .phone("01023698745")
                .nickname("name")
                .password("temp123!")
                .confirmPassword("temp123!")
                .build();

        // when // then
        doThrow(new BusinessException(ErrorCode.DUPLICATED_EMAIL))
                .when(userService).create(any(SignUpRequestDTO.class));

        mockMvc.perform(post("/api/v2/users/new")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(signUpDto)))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.errorMessage").value("이미 존재하는 이메일 입니다."));

        // 회원 생성 메소드가 호출되었는지 확인
        verify(userService).create(refEq(signUpDto));
    }
}

@AutoConfigureMockMvc(addFilters = false)

  * MockMvc 객체(HTTP 요청과 응답을 모킹(mocking)하여 컨트롤러의 동작을 테스트할 수 있는 객체)를 자동으로 설정

  * addFilters = false: Spring Security와 같은 필터를 적용하지 않도록 설정

 

MockMvc

  * HTTP 요청과 응답을 모킹(mocking, 실제 서버에 HTTP 요청을 보내지 않고, 테스트 환경에서 HTTP 요청을 모방하여 응답을 받을 수 있도록 하는 것)하여 컨트롤러의 동작을 테스트할 수 있는 객체

  * 실제 서버를 띄우지 않고도 컨트롤러와 상호작용할 수 있음

 

ObjectMapper

  * Java 객체를 JSON으로 직렬화하거나, 반대로 JSON을 Java 객체로 역직렬화

    * objectMapper.writeValueAsString: 객체를 JSON으로 직렬화 -> request body에 저장

 

@MockBean

  * 테스트 시, UserService 클래스의 가짜(Mock) 객체를 생성

  * UserService 사용 시, 실제로 데이터베이스에 접근하거나 복잡한 로직을 처리하지 않고, 테스트에서 설정한 동작만을 수행

    * doThrow(): 예외가 발생하도록 모킹

    * doNothing(): 메소드를 호출 시, 아무런 동작도 하지 않도록 모킹

  * 특정 메소드가 호출되었는지, 또는 어떤 인자를 전달받았는지 확인할 수 있음

 

mockMvc.perform()

  * MockMvc를 사용해 GET/POST/PUT/PATCH/DELETE 요청

 

verify()

  * 메소드가 호출 확인

  * refEq(): 값 비교

 

 

 

🙋‍♀️

본 포스트는 공부 목적으로 작성하였습니다.
보시는 도중 잘못된 부분이나 개선할 부분이 있다면 댓글로 알려주시면 수정하도록 하겠습니다.

 

📑

참고 자료

https://sbs1621.tistory.com/54

 

[Spring] MockMvc를 이용한 Controller의 Test Code(JUnit5) 작성하기

간단하게 작성할 수 있는 게시판 Controller에 대한 테스트코드입니다. 테스트코드 추가하기 컨트롤러에서 cmd + shift + t(윈도우는 control + shift + t)를 누르시면 간단하게 테스트코드를 만들 수 있습

sbs1621.tistory.com