1년 전 진행했던 마실가실 프로젝트를 🛠️리팩토링하며 정리한 내용입니다.
사실 테스트 코드 작성 관련해서는 이전에 한 번 글을 쓴 적이 있습니다.
그 때는 Service 코드를 검증하였습니다.
Spring 강의를 들을 때, 테스트 코드를 Service 단에서 작성했기에 해당 코드를 응용해가며 리팩토링할 때 테스트 코드를 만들어갈 수 있었습니다.
하지만, Controller는 테스트 코드를 작성해본 적이 없습니다..?
그래서 PostMan을 사용하다가, Postman에서 검증이 다 끝났기에 Test Code를 공부하면서 작성해보면 좋을 것 같아 글을 작성하게 되었습니다.
Contoller 테스트 코드를 작성하며 쓰는, PostMan과 헤어질 결심..!
https://hj0216.tistory.com/933
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
'PlayGround > 마실가실 리팩토링' 카테고리의 다른 글
[1년 후 마실가실] .gitignore 재적용 (0) | 2024.09.23 |
---|---|
[1년 후 마실가실] @WebMvcTest Security 403 (0) | 2024.09.21 |
[1년 후 마실가실] Spring Security 특정 url 제외 (1) | 2024.09.18 |
[1년 후 마실가실] Custom Error 처리 (0) | 2024.09.17 |
[1년 후 마실가실] JWT와 로그아웃(3) 로그아웃 (0) | 2024.09.16 |