From 580ea09dcb2d259458bbbcf1536b7fbf2832b59c Mon Sep 17 00:00:00 2001 From: bum12ark Date: Fri, 4 Feb 2022 19:59:12 +0900 Subject: [PATCH] =?UTF-8?q?test(user-service):=20=ED=9A=8C=EC=9B=90=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원 조회 테스트 추가 - 회원 조회 (존재하지 않는 회원) 테스트 추가 --- user-service/src/docs/asciidoc/api-docs.adoc | 71 +++++++++++ .../domain/user/dto/CustomerDto.java | 6 + .../userservice/domain/user/dto/UserDto.java | 8 ++ .../domain/user/web/UserController.java | 4 +- .../userservice/config/TestConfig.java | 18 +++ .../domain/user/web/UserControllerTest.java | 118 ++++++++++++++++++ 6 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 user-service/src/docs/asciidoc/api-docs.adoc create mode 100644 user-service/src/test/java/com/justpickup/userservice/config/TestConfig.java create mode 100644 user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc new file mode 100644 index 0000000..dfde993 --- /dev/null +++ b/user-service/src/docs/asciidoc/api-docs.adoc @@ -0,0 +1,71 @@ +:doctype: book +:icons: font +:source-highlighter: highlightjs +:toc: left +:toclevels: 2 +:sectlinks: + + +[[overview]] += 개요 + +[[overview-http-verbs]] +== HTTP 동사 + +본 REST API에서 사용하는 HTTP 동사(verbs)는 가능한한 표준 HTTP와 REST 규약을 따릅니다. + +|=== +| 동사 | 용례 + +| `GET` +| 리소스를 가져올 때 사용 + +| `POST` +| 새 리소스를 만들 때 사용 + +| `PUT` +| 기존 리소스를 수정할 때 사용 + +| `PATCH` +| 기존 리소스의 일부를 수정할 때 사용 + +| `DELETE` +| 기존 리소스를 삭제할 떄 사용 +|=== + +[[overview-http-status-codes]] +== HTTP 상태 코드 + +본 REST API에서 사용하는 HTTP 상태 코드는 가능한 표준 HTTP와 REST 규약을 따릅니다. + +|=== +| 상태 코드 | 용례 + +| `200 OK` +| 요청을 성공적으로 처리함 + +| `201 Created` +| 새 리소스를 성공적으로 생성함. 응답의 `Location` 헤더에 해당 리소스의 URI가 담겨있다. + +| `204 No Content` +| 기존 리소스를 성공적으로 수정함. + +| `400 Bad Request` +| 잘못된 요청을 보낸 경우. 응답 본문에 더 오류에 대한 정보가 담겨있다. + +| `404 Not Found` +| 요청한 리소스가 없음. + +| `409 Conflict` +| 클라이언트의 요청이 서버의 상태와 충돌이 발생한 경우. +|=== + +[[snippets-write-convention]] +== snippets 작성 컨벤션 +domain-httpRequestCode-etc + +== 유저 +=== 회원 조회 +operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] +=== 회원 조회 (존재하지 않는 회원) +operation::customer-get-notExistUserException[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] \ No newline at end of file diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java index dabe187..ac60aa5 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/CustomerDto.java @@ -1,6 +1,7 @@ package com.justpickup.userservice.domain.user.dto; import com.justpickup.userservice.domain.user.entity.Customer; +import lombok.Builder; import lombok.Getter; @Getter @@ -9,4 +10,9 @@ public class CustomerDto extends UserDto { public CustomerDto(Customer customer) { super(customer); } + + @Builder + public CustomerDto(Long id, String password, String name, String phoneNumber) { + super(id, password, name, phoneNumber); + } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java index 60596ee..3fad831 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/dto/UserDto.java @@ -1,6 +1,7 @@ package com.justpickup.userservice.domain.user.dto; import com.justpickup.userservice.domain.user.entity.Customer; +import lombok.Builder; import lombok.Getter; @Getter @@ -17,4 +18,11 @@ public class UserDto { this.name = customer.getName(); this.phoneNumber = customer.getPhoneNumber(); } + + public UserDto(Long id, String password, String name, String phoneNumber) { + this.id = id; + this.password = password; + this.name = name; + this.phoneNumber = phoneNumber; + } } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java index 53c6431..ba35d4b 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; + @RestController @RequiredArgsConstructor @Slf4j @@ -22,7 +24,7 @@ public class UserController { private final UserService userService; @GetMapping("/customer/{userId}") - public ResponseEntity getCustomer(@PathVariable("userId") Long userId) { + public ResponseEntity getCustomer(@Valid @PathVariable("userId") Long userId) { CustomerDto customerDto = userService.findCustomerByUserId(userId); diff --git a/user-service/src/test/java/com/justpickup/userservice/config/TestConfig.java b/user-service/src/test/java/com/justpickup/userservice/config/TestConfig.java new file mode 100644 index 0000000..4a67747 --- /dev/null +++ b/user-service/src/test/java/com/justpickup/userservice/config/TestConfig.java @@ -0,0 +1,18 @@ +package com.justpickup.userservice.config; + +import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; + +@TestConfiguration +public class TestConfig { + + @Bean + public RestDocsMockMvcConfigurationCustomizer restDocsMockMvcConfigurationCustomizer() { + return configurer -> configurer.operationPreprocessors() + .withRequestDefaults(prettyPrint()) + .withResponseDefaults(prettyPrint()); + } +} diff --git a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java new file mode 100644 index 0000000..d27be15 --- /dev/null +++ b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java @@ -0,0 +1,118 @@ +package com.justpickup.userservice.domain.user.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.justpickup.userservice.config.TestConfig; +import com.justpickup.userservice.domain.user.dto.CustomerDto; +import com.justpickup.userservice.domain.user.exception.NotExistUserException; +import com.justpickup.userservice.domain.user.service.UserService; +import com.justpickup.userservice.global.dto.Code; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@WebMvcTest(UserController.class) +@Import(TestConfig.class) +@AutoConfigureRestDocs(uriHost = "127.0.0.1", uriPort = 8001) +class UserControllerTest { + + @Autowired + ObjectMapper objectMapper; + + @Autowired + MockMvc mockMvc; + + @MockBean + UserService userService; + + @Test + @DisplayName("회원 조회") + void getCustomer() throws Exception { + // GIVEN + long userId = 1L; + + CustomerDto willReturnDto = CustomerDto.builder() + .id(1L) + .name("이름") + .password("password!@#") + .phoneNumber("010-1234-5678") + .build(); + + given(userService.findCustomerByUserId(userId)) + .willReturn(willReturnDto); + + // WHEN + ResultActions actions = mockMvc.perform(get("/customer/{userId}", userId)); + + // THEN + actions.andExpect(status().isOk()) + .andExpect(jsonPath("code").value(Code.SUCCESS.name())) + .andExpect(jsonPath("message").value("")) + .andExpect(jsonPath("data.userId").value(1)) + .andExpect(jsonPath("data.userName").value("이름")) + .andExpect(jsonPath("data.phoneNumber").value("010-1234-5678")) + .andDo(print()) + .andDo(document("customer-get", + pathParameters( + parameterWithName("userId").description("회원 고유번호") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data.userId").description("회원 고유번호"), + fieldWithPath("data.userName").description("회원 이름"), + fieldWithPath("data.phoneNumber").description("회원 휴대폰 번호") + )) + ) + ; + } + + @Test + @DisplayName("회원 조회 - 존재하지 않는 회원") + void getCustomerNotExistUserException() throws Exception { + // GIVEN + long notExistUserId = 9999L; + String message = "존재하지 않는 회원 입니다."; + given(userService.findCustomerByUserId(notExistUserId)) + .willThrow(new NotExistUserException(message)); + + // WHEN + ResultActions actions = mockMvc.perform(get("/customer/{userId}", notExistUserId)); + + // THEN + actions.andExpect(status().isConflict()) + .andExpect(jsonPath("code").value(Code.ERROR.name())) + .andExpect(jsonPath("message").value(message)) + .andExpect(jsonPath("data").isEmpty()) + .andDo(print()) + .andDo(document("customer-get-notExistUserException", + pathParameters( + parameterWithName("userId").description("회원 고유번호") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data").description("데이터") + ) + )) + ; + } +} \ No newline at end of file