봄수의 연구실

🐥 카카오 테크 캠퍼스 - 2단계 4주차 과제 분석 본문

프로젝트/카카오 테크 캠퍼스

🐥 카카오 테크 캠퍼스 - 2단계 4주차 과제 분석

berom 2023. 7. 19. 14:48

핵심 지표

  • 컨트롤러 단위테스트가 구현되었는가?
  • Mockito를 이용하여 stub을 구현하였는가?
  • 인증이 필요한 컨트롤러를 테스트할 수 있는가?
  • 200 ok만 체크한 것은 아닌가? (해당 컨트롤러에서 제일 필요한 데이터에 대한 테스트가 구현되었는가?)
  • 모든 요청과 응답이 json으로 처리되어 있는가?

과제 고도화

  • DB 연결 없이 컨트롤러 테스트를 모두 진행하라
  • Repository도 만들고, 서비스도 다 만들어서 테스트

User

단일 유저 조회: Get /users/{id}

@GetMapping("/users/{id}")
public ResponseEntity<?> findById(
        @PathVariable Integer id,
        @AuthenticationPrincipal CustomUserDetails userDetails,
        HttpServletRequest request
) {
    // Code block
}

Test Code

@Test  
public void findById_test() throws Exception {  
	// given  
	User user = User.builder().id(1).roles("ROLE_USER").build();  
	UserResponse.FindById responseDTO = new UserResponse.FindById(user);  
	Mockito.when(userService.findById(1)).thenReturn(responseDTO);  
	  
	// stub  
	String jwt = JWTProvider.create(user);  
	Mockito.when(userService.login(any())).thenReturn(jwt);  
	  
	// when  
	ResultActions result = mvc.perform(  
	MockMvcRequestBuilders  
		.get("/users/{id}", 1)  
		.header(JWTProvider.HEADER, jwt)  
		.contentType(MediaType.APPLICATION_JSON)  
	);  
	  
	String responseBody = result.andReturn().getResponse().getContentAsString();  
	System.out.println("테스트 : "+responseBody);  
	  
	// then  
	result.andExpect(MockMvcResultMatchers.jsonPath("$.success").value("true"));  
	Assertions.assertTrue(jwt.startsWith(JWTProvider.TOKEN_PREFIX));  
}

회원 가입: Post /join

@PostMapping("/join")
public ResponseEntity<?> join(@RequestBody @Valid UserRequest.JoinDTO requestDTO, Errors errors,
                              HttpServletRequest request) {
    // Code block
}

Test Code

@Test  
public void join_test() throws Exception {  
	// given  
	UserRequest.JoinDTO requestDTO = new UserRequest.JoinDTO();  
	requestDTO.setEmail("ssarmango@nate.com");  
	requestDTO.setPassword("meta1234!");  
	requestDTO.setUsername("ssarmango");  
	String requestBody = om.writeValueAsString(requestDTO);  
	  
	// when  
	ResultActions result = mvc.perform(  
	MockMvcRequestBuilders  
		.post("/join")  
		.content(requestBody)  
		.contentType(MediaType.APPLICATION_JSON)  
	);  
	  
	String responseBody = result.andReturn().getResponse().getContentAsString();  
	System.out.println("테스트 : "+responseBody);  
	  
	// then  
	result.andExpect(MockMvcResultMatchers.jsonPath("$.success").value("true"));  
}

로그인: Post /login

  • 인증
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody @Valid UserRequest.LoginDTO requestDTO, Errors errors, HttpServletRequest request) {
    // Code block
}

Test Code

@Test  
public void login_test() throws Exception {  
	// given  
	UserRequest.LoginDTO loginDTO = new UserRequest.LoginDTO();  
	loginDTO.setEmail("ssar@nate.com");  
	loginDTO.setPassword("meta1234!");  
	User user = User.builder().id(1).roles("ROLE_USER").build();  
	String requestBody = om.writeValueAsString(loginDTO);  
	  
	// stub  
	String jwt = JWTProvider.create(user);  
	Mockito.when(userService.login(any())).thenReturn(jwt);  
	  
	// when  
	ResultActions result = mvc.perform(  
	MockMvcRequestBuilders  
		.post("/login")  
		.content(requestBody)  
		.contentType(MediaType.APPLICATION_JSON)  
	);  
	String responseBody = result.andReturn().getResponse().getContentAsString();  
	String responseHeader = result.andReturn().getResponse().getHeader(JWTProvider.HEADER);  
	
	System.out.println("테스트 : "+responseBody);  
	System.out.println("테스트 : "+responseHeader);  
	
	// then  
	result.andExpect(MockMvcResultMatchers.jsonPath("$.success").value("true"));  
	Assertions.assertTrue(jwt.startsWith(JWTProvider.TOKEN_PREFIX));  
}

비밀 번호 변경: Post /users/{id}/update-password

  • 인증
@PostMapping("/users/{id}/update-password")
public ResponseEntity<?> updatePassword(
        @PathVariable Integer id,
        @RequestBody @Valid UserRequest.UpdatePasswordDTO requestDTO, Errors errors,
        @AuthenticationPrincipal CustomUserDetails userDetails,
        HttpServletRequest request) {
    // Code block
}

이메일 중복 체크: Post /check - 기능 명세 x

@PostMapping("/check")
public ResponseEntity<?> check(@RequestBody UserRequest.EmailCheckDTO emailCheckDTO) {
    // Code block
}

로그아웃: Get /logout - 기능 명세 x

@GetMapping("/logout")  
public ResponseEntity<?> logout(@RequestBody Map<String, String> user) {  
	return ResponseEntity.ok().header(JWTProvider.HEADER, "").body(ApiUtils.success(null));  
}

Cart

장바구니 담기: Post /carts/add

  • 인증
@PostMapping("/carts/add")
public ResponseEntity<?> addCartList(@RequestBody List<CartRequest.SaveDTO> requestDTOs, @AuthenticationPrincipal CustomUserDetails userDetails) {
    // Code block
}

장바구니 조회: Get /carts

  • 인증
@GetMapping("/carts")
public ResponseEntity<?> findAll(@AuthenticationPrincipal CustomUserDetails userDetails) {
    // Code block
}

장바구니 수정: Post /carts/update

  • 인증
@PostMapping("/carts/update")
public ResponseEntity<?> update(@RequestBody @Valid List<CartRequest.UpdateDTO> requestDTOs, @AuthenticationPrincipal CustomUserDetails userDetails) {
    // Code block
}

장바구니 비우기: Post /carts/clear

  • 인증
@PostMapping("/carts/clear")
public ResponseEntity<?> clear(@AuthenticationPrincipal CustomUserDetails userDetails) {
    // Code block
}

Order

결재: Post /orders/save

  • 인증
@PostMapping("/orders/save")
public ResponseEntity<?> save(@AuthenticationPrincipal CustomUserDetails userDetails) {
    // Code block
}

주문 조회: Get /orders/{id}

  • 인증
@GetMapping("/orders/{id}")
public ResponseEntity<?> findById(@PathVariable int id) {
    // Code block
}

Product

전체 상품 목록 조회: Get /products

@GetMapping("/products")
public ResponseEntity<?> findAll(@RequestParam(defaultValue = "0") int page) {
    // Code block
}

개별 상품 상세 조회: Get /products/{id}

@GetMapping("/products/{id}")
public ResponseEntity<?> findById(@PathVariable int id) {
    // Code block
}

모호하다

@WebMvcTest(controllers = {UserRestController.class})

  • WebMvcTest

import 하는 이유

@Import({  
	SecurityConfig.class,  
	GlobalExceptionHandler.class  
})

Transactional 에서 Osive 알자

부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>

728x90