회원가입 controller의 test code를 추가하였다.
회원가입 성공, 실패 두가지 case에 대해 실행하였다.
1. TestCode
UserControllerTest
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
MockMvc mockMvc;
@MockBean
UserService userService;
@Autowired
ObjectMapper objectMapper;
@Test
@DisplayName("회원가입 성공")
@WithMockUser
void join_success() throws Exception{
UserJoinRequest userJoinRequest = UserJoinRequest.builder()
.userName("haneul")
.password("1234")
.build();
when(userService.join(any())).thenReturn(mock(UserDto.class));
mockMvc.perform(post("/api/v1/users/join")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(userJoinRequest)))
.andDo(print())
.andExpect(status().isOk());
}
@Test
@DisplayName("회원가입 실패 - userName 중복")
@WithMockUser
void join_fail() throws Exception{
UserJoinRequest userJoinRequest = UserJoinRequest.builder()
.userName("haneul")
.password("1234")
.build();
when(userService.join(any()))
.thenThrow(new AppException(ErrorCode.DUPLICATED_USER_NAME, ""));
mockMvc.perform(post("/api/v1/users/join")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsBytes(userJoinRequest)))
.andDo(print())
.andExpect(status().isConflict());
}
}
Layered architecture에서 controller는 service를 의존하고, service는 repository를 의존하고 있기 때문에, test code에서 controller를 불러와 test를 하고 싶으면 service와 repository를 다 불러와야된다.
-> unit test 성립이 안되고, test 실행 시간도 길어지고, db dependency가 생기게 된다.
-> test의 원칙에 잘 맞지 않게 된다.
따라서 Mock을 이용한다.
- Mock : 가짜 객체. service (ex findById(id))가 실행되었다 가정하고, return값을 넣어준다. 빠르게 고립된 테스트가 가능하다.
MockMvc에 요청한 응답에 대하여 expect가 모두 통과하면 test success.
실패시 해당하는 httpStatus가 나오는지와, 성공시 status가 200이 나오는지 test해본다.
- .writeValueAsBytes : Object를 JSON으로 만들어 준 후, byte 배열로 반환해준다.
- @WebMvcTest : @SpringBootTest은 모든 bean을 불러오기 때문에 시간이 오래 걸리고, test 단위가 크다. 따라서 controller만을 test하고 싶을 때, 위의 annotation을 이용한다.
- @MockBean : 가짜 객체를 생성하여 주입힌다. 이 test에는 service를 선언하기 위해 사용하였다. service와의 dependency를 걱정할 필요가 없다.
- MockMvc : 배포하지 않고도, 서버의 MVC 동작을 테스트 할 수 있는 라이브러리이다.
- perform : 요청을 전송하는 역할.
- get : HTTP method( get(), post(), put(), delete() )를 결정할 수 있다. 통신의 경로를 지정해 준다.
- andExpect() : 응답을 검증하는 method이다.
- andDo(print()) : 요청/응답 전체 메세지를 확인.
<전체 Reference>
https://shinsunyoung.tistory.com/52
'프로젝트 > 멋사 개인 프로젝트 (mutsa-SNS)' 카테고리의 다른 글
[06] mutsa-SNS 3일차 - (1) User 수정 (0) | 2022.12.22 |
---|---|
[05] mutsa-SNS 2일차 - (2) 로그인 기능 (1) | 2022.12.21 |
[03] mutsa-SNS 1일차 - (2) 회원 가입 기능 (0) | 2022.12.21 |
[02] mutsa-SNS 1일차 - (1) CI/CD 설정 (0) | 2022.12.21 |
[01] 1주차/2주차 미션 개요 (0) | 2022.12.21 |