Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4기 - 소재훈] SpringBoot Part2 Weekly Mission 제출합니다. #852

Open
wants to merge 159 commits into
base: jay-so
Choose a base branch
from

Conversation

jay-so
Copy link
Member

@jay-so jay-so commented Jul 18, 2023

📌 과제 설명

  •  바우처 관리 애플리케이션에 단위테스트를 작성해보세요.
  • 가능한 많은 단위 테스트코드를 작성하려고 노력해보세요.
  • 엣지 케이스(예외 케이스)를 고려해서 작성해주세요..
  • 바우처 관리 애플리케이션에서도 과정에서 다루었던 고객을 적용해보세요
  • customers 테이블 정의 및 추가
  • CustomerRepository 추가 및 JdbcTemplate을 사용해서 구현
  • 바우처에 엔터티에 해당하는 vouchers 테이블을 한번 정의해보세요.
  • 바우처 레포지토리를 만들어보세요. (JdbcTemplate을 사용해서 구현)
  • 기존의 파일에서 바우처를 관리한 것을 vouchers 테이블을 통해서 CRUD가 되게 해보세요.

👩‍💻 요구 사항과 구현 내용


🧑🏻‍💻 프로그램 작동 설명


1️⃣ 메인화면


  • Voucher(바우처 관련 프로그램)
  • Customer(고객 관련 프로그램)
  • Exit(프로그램 종료)
==== Voucher Program ====
 다음 아래의 3개의 프로그램 명령 중 하나를 선택해주세요.
Voucher : 바우처 관련 프로그램 시작
Customer : 고객 관련 프로그램 시작
Exit: 프로그램 종료
input : 

2️⃣ Voucher(바우처 관련 프로그램 화면) - (메인 화면에서 voucher 입력 시)


  • 바우처 생성(Create)
  • 바우처 조회(Select)
  • 바우처 변겅(Update)
  • 바우처 삭제(Delete)
==== Voucher Program ====
바우처 관련 프로그램을 시작합니다.
다음의 명령어 Create, Select, Update, Delete 중 하나를 입력해주세요.
바우처 생성: Create
바우처 조회: Select
바우처 변경: Update
바우처 삭제: Delete

3️⃣ 바우처 생성(Create)


  • 고정 금액 할인 바우처 생성 : fixed 입력
  • 비율 금액 할인 바우처 생성 : Rate 입력
==== Voucher 생성 작업 ====
생성 가능한 바우처의 타입을 확인 후, 입력해 주세요!
정액 할인 바우처(고정 금액 할인)는 fixed를 입력해주세요.
정률 할인 바우처(비율 금액 할인)는 Rate를 입력해주세요.

  • 정액 할인 바우처 생성 범위 : 0 초과의 숫자를 입력
  • 정률 할인 바우처 생성범위 : 1 ~ 99까지의 비율 입력
==== Voucher 생성 작업 ==== 
생성할 바우처의 종류에 따른 입력 금액을 확인 후, 입력해 주세요!
정액 할인 바우처(고정 금액 할인)의 경우, 0이하의 숫자를 제외한 금액을 입력할 수 있습니다.
정률 할인 바우처(비율 금액 할인)의 경우, 1 ~ 99까지의 비율을 입력할 수 있습니다.

4️⃣ 바우처 조회 작업(Select)


  • All : 생성된 모든 바우처 조회
  • ID : 생성된 바우처 ID를 통해 조회
  • Type : 바우처 타입별로 조회
  • CreatedAt : 바우처 생성일 순으로 조회
==== Voucher 조회 작업 ==== 
바우처의 다음의 조회 방법에 대해서 확인 후, 입력해 주세요! 
All : 모든 바우처를 조회
ID : 바우처의 ID로 조회
Type: 바우처의 타입별로 조회
CreatedAt : 바우처의 생성일 순으로 조회 

  1. All : 생성된 모든 바우처 목록 조회
==== Voucher 조회 작업 ==== 
저장된 모든 바우처를 조회를 수행합니다.
바우처 ID : 3729290f-1f98-43ad-af18-ad4ea416084b
할인 금액 : 5000
바우처 타입 : FIXED
바우처 생성일 :2023-07-18T23:36:35.045897


==== Voucher 조회 작업 ==== 
저장된 모든 바우처를 조회를 수행합니다.
바우처 ID : 856ec06b-2ca1-4fea-9bc3-d1bf5b7b10d6
할인 금액 : 50
바우처 타입 : RATE
바우처 생성일 :2023-07-18T23:36:46.949358

  1. ID : 생성된 바우처 ID로 조회
==== Voucher 조회 작업 ==== 
조회할 바우처의 ID를 입력해주세요!
input : 856ec06b-2ca1-4fea-9bc3-d1bf5b7b10d6
해당 바우처의 ID: 856ec06b-2ca1-4fea-9bc3-d1bf5b7b10d6
해당 바우처의 금액: 50
해당 바우처의 타입: RATE
해당 바우처의 생성일:2023-07-18T23:36:46.949358

  1. Type: 타입별(정액, 정률) 바우처 조회
==== Voucher 조회 작업 ==== 
조회할 바우처의 Type을 입력해주세요!
fixed : 정액 할인 바우처(고정 금액 할인)
rate : 정률 할인 바우처(비율 금액 할인)
input : fixed

==== Voucher 조회 작업 ==== 
 저장된 바우처를 타입별 조회를 수행합니다.

바우처 ID : 3729290f-1f98-43ad-af18-ad4ea416084b
할인 금액 : 5000
바우처 타입 :  FIXED
바우처 생성일 :2023-07-18T23:36:35.045897

  1. createdat : 생성일 순으로 바우처 조회
==== Voucher 조회 작업 ==== 
바우처를 생성일순으로 조회합니다.


==== Voucher 조회 작업 ==== 
저장된 모든 바우처를 조회를 수행합니다.
바우처 ID : 3729290f-1f98-43ad-af18-ad4ea416084b
할인 금액 : 5000
바우처 타입 : FIXED
바우처 생성일 :2023-07-18T23:36:35.045897


==== Voucher 조회 작업 ==== 
저장된 모든 바우처를 조회를 수행합니다.
바우처 ID : 856ec06b-2ca1-4fea-9bc3-d1bf5b7b10d6
할인 금액 : 50
바우처 타입 : RATE
바우처 생성일 :2023-07-18T23:36:46.949358

5️⃣ 바우처 변경 작업(Update)


  • 정액 할인 바우처(Fixed) : 0 초과의 금액 변경 가능
  • 정률 할인 바우처(Rate) : 1 ~ 99까지의 비율 범위로 금액 변경 가능
==== Voucher 수정 작업 ==== 
바우처 수정을 선택하셨습니다.

수정할 바우처의 ID를 입력해주세요.
input : 3729290f-1f98-43ad-af18-ad4ea416084b
변경할 금액 : 10000
변경 후 금액 : 10000
정상적으로 해당 작업이 완료되었습니다!

6️⃣ 바우처 삭제 작업(Delete)


  • id : 바우처의 id로 해당 바우처 삭제
  • all : 저장된 모든 바우처 삭제 가능
삭제할 바우처의 ID를 입력해주세요.
input: 3729290f-1f98-43ad-af18-ad4ea416084b
정상적으로 해당 작업이 완료되었습니다!
input : all
모든 바우처들을 삭제를 선택하셨습니다!
정상적으로 해당 작업이 완료되었습니다!


7️⃣ Customer(고객 관련 프로그램 화면) - (메인 화면에서 customer 입력 시)


==== Customer 프로그램 작업 ==== 
아래의 명령어(Create,Select,Update,Delete) 중 하나를 입력해주세요
고객 생성: Create
고객 조회: Select
고객 변경: Update
고객 삭제: Delete

8️⃣ 고객 생성(Create)


  • 고객 이름 : 영문만 입력받도록 제한함
  • 이메일 : 이메일 형식만 입력받도록 제한함
===== Customer 생성 작업 ====
반드시 다음과 같은 순서로 입력해주세요!
1.고객 이름(Name)
2.고객 이메일(Email)
input(이름) : so
input(Email) :  merry9320@naver.com
정상적으로 해당 작업이 완료되었습니다!

9️⃣ 고객 조회 작업(Select)


  • All : 생성된 모든 고객 조회
  • ID : 생성된 고객 ID를 통해 조회
  • CreatedAt : 고객 생성일 순으로 조회
==== Customer 조회 작업 ==== 
고객 조회에 대해서  다음의 방법을 확인 후, 입력해 주세요! 
ID : 고객의 ID로 조회
CreatedAt : 고객의 생성일 순으로 조회 
ALL: 모든 고객을 조회

  1. All : 생성된 모든 고객 목록 조회
==== Customer 조회 작업 ==== 
저장된 모든 고객을 조회를 수행합니다.
고객 ID : 4aa251e1-0a60-4400-b682-a8e3e343422a
고객 Name : so
고객 Email :  merry9320@naver.com
고객 생성일 :2023-07-18T23:57:38.019454

  1. ID : 생성된 고객 ID로 조회
==== Customer 조회 작업 ==== 
조회할 고객의 ID를 입력해주세요!
input : 4aa251e1-0a60-4400-b682-a8e3e343422a
해당 고객의 ID: 4aa251e1-0a60-4400-b682-a8e3e343422a
해당 고객의 이름: so
해당 고객의 이메일: merry9320@naver.com
해당 고객의 생성일: 2023-07-18T23:57:38.019454

  1. createdat : 생성일 순으로 고객 조회
==== 고객 조회 작업(생성일 순) ==== 
저장된 모든 고객를 조회를 수행합니다.
고객 ID : 4aa251e1-0a60-4400-b682-a8e3e343422a
고객 이름 : so
고객 이메일 : merry9320@naver.com
고객 생성일 :2023-07-18T23:57:38.019454


==== 고객 조회 작업(생성일 순) ==== 
저장된 모든 고객를 조회를 수행합니다.
고객 ID : 4812c84a-c831-4af6-bd93-c60b513749cc
고객 이름 : hanjo
고객 이메일 : hanjo9605@programmers.com
고객 생성일 :2023-07-19T00:01:05.567885


🔟 고객 변경 작업(Update)


  • 고객 이름: 영문만 가능하도록 제한
  • 이메일 : 이메일 형식만 가능하도록 제한
수정햘 고객의 ID를 입력해주세요.
input : 4812c84a-c831-4af6-bd93-c60b513749cc
변경할 이름 : jaewon
변경할 이메일 : hanjo9607@programmers.com
정상적으로 해당 작업이 완료되었습니다!

🕚 고객 삭제 작업(Delete)


  • id : 고객의 id로 해당 고객 삭제
  • all : 저장된 모든 고객 삭제 가능

ID: 고객의  ID를 통해 해당 바우처 삭제
ALL : 모든 고객을 삭제 
input : id

삭제할 고객의 ID를 입력해주세요.
input : 4812c84a-c831-4af6-bd93-c60b513749cc
정상적으로 해당 작업이 완료되었습니다!
ID: 고객의  ID를 통해 해당 바우처 삭제
ALL : 모든 고객을 삭제 
input : all

==== Customer 삭제 작업 ==== 
모든 고객 삭제를 선택하셨습니다!


✅ 피드백 반영사항

  • 지난 PR 당시 서비스단에서 validation을 도메인에서 수행되면 좋겠다는 피드백을 반영하였습니다!
  • "해피 테스트 케이스만 있지 말고, 엣지 테스트 케이스가 있으면 좋겠다!" 라는 피드백을 받아, 도메인 VoucherTest, CustomerTest, VoucherService 테스트에 가능한 많은 엣지 테스트 케이스를 작성했습니다!

✅ PR 포인트 & 궁금한 점

-> 😭😭 설정 조건들이 많아, 모든 테스트 케이스(해피 테스트 케이스, 엣지 테스트 케이스)를 작성하지 못했습니다. (VoucherJdbcRepository,CustomerService 미작성)
-> 3차 미션 진행 중, 혹은 후에 테스트 케이스를 추가하도록 노력하겠습니다!
-> 피드백을 남겨주신 후 빠르게 확인하여 3차 미션에서 반영하도록 노력하겠습니다!

jay-so added 30 commits July 4, 2023 00:30
Copy link

@hanjo8813 hanjo8813 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재훈님 수고하셨습니다~!

요구사항보다 기능을 추가하신게 많아서 리뷰가 매우 많이 달렸습니다. 56개는 처음입니다... ㅋㅋㅋㅋㅋㅋ
리뷰해보니 다음 미션부터는 웬만하면 다른 기능을 추가하기보다, 요구사항만 구현하되 최대한 코드 퀄리티를 높이는데에 집중하는 게 더 좋을것 같습니다.
(추가 기능구현 금지!!)

중복되는 리뷰는 최대한 생략했으니, 리뷰가 달린 곳만 리팩토링하지 마시고 전체적으로 동일한 부분을 고쳐주시기 바랍니다~

private void selectCustomer() {
console.printCustomerSelectMenu();
//선택 - Id, CreateAt, All
switch (CustomerSelectMenu.of(console.inputCommand())) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정확히 어떤걸 의미하는지 나타내기 위해 이름을 가진 변수로 빼주는게 좋을것 같아요~

Comment on lines +79 to +83
if (!customerListResponse.getCustomerResponseList().isEmpty()) {
console.printCustomerSelectByCreatedAt(customerListResponse);
} else {
console.printErrorMessage("현재 저장된 고객이 존재하지 않습니다.");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

early return을 사용해보는건 어떨까요?
그리고 가독성을 높이기 위해 조건문의 순서를 바꿔주면 좋을것 같습니다.

Suggested change
if (!customerListResponse.getCustomerResponseList().isEmpty()) {
console.printCustomerSelectByCreatedAt(customerListResponse);
} else {
console.printErrorMessage("현재 저장된 고객이 존재하지 않습니다.");
}
if (customerListResponse.getCustomerResponseList().isEmpty()) {
console.printErrorMessage("현재 저장된 고객이 존재하지 않습니다.");
break;
}
console.printCustomerSelectByCreatedAt(customerListResponse);

Comment on lines +88 to +92
if (!customerListResponse.getCustomerResponseList().isEmpty()) {
console.printCustomerSelectAll(customerListResponse);
} else {
console.printErrorMessage("현재 저장된 고객이 없습니다.");
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 리뷰처럼 더 간결하게 바꿔주세요~

Comment on lines +35 to +37
public CustomerListResponse findByCreateAt() {
return customerService.findByCreateAt();
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 메소드 네이밍은 생성일로 특정 고객을 찾는다는 생각이 들게합니다.
모든 고객을 생성일 순으로 조회하는 것이니, 메소드 명은 아래처럼 바꾸는게 더 적합해 보이네요.

Suggested change
public CustomerListResponse findByCreateAt() {
return customerService.findByCreateAt();
}
public CustomerListResponse findAllOrderByCreatedAt() {
return customerService.findAllOrderByCreatedAt();
}

Comment on lines +71 to +74
String email = "valid@example.com";

assertThat(new Customer(UUID.randomUUID(), "ValidName", email, LocalDateTime.now()).getEmail(), is(equalTo(email)));
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떤 동작인지 읽기가 힘드네요,, ㅜ
항상 given-when-then 패턴을 지켜주세요..!


//해피 케이스 테스트 - Hamcrest 테스트
@Test
@DisplayName("고객 생성 테스트")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전 PR 리뷰 피드백이 되지 않은것 같습니다.
#775 (comment)

모든 DisplayName에서 멘토님께서 늘 강조하시는 테스트 설명 규칙을 꼭 지켜주세요.
참고 : #755 (review)

Comment on lines +91 to +99
UUID customerId = UUID.randomUUID();
LocalDateTime createdAt = LocalDateTime.now();

Customer customer = new Customer(customerId, name, email, createdAt);

assertThat(customer.getCustomerId(), is(equalTo(customerId)));
assertThat(customer.getName(), is(equalTo(name)));
assertThat(customer.getEmail(), is(equalTo(email)));
assertThat(customer.getCreateAt(), is(equalTo(createdAt)));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given-when-then

Comment on lines +52 to +53
//then
assertThrows(IllegalArgumentException.class, () -> new FixedVoucher(discount));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when + then이겠죠?

Comment on lines +25 to +28
@ActiveProfiles("test")
@SpringBootTest
@Transactional
class VoucherServiceTest {
Copy link

@hanjo8813 hanjo8813 Jul 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전 테스트에서 mocking을 사용하셨었는데 이렇게 변경하신 이유는 뭘까요?
@SpringBootTest가 단위테스트에 적합할까요?

단위테스트의 두가지 방식에 대해서도 고민해보세요. (고전파 vs 런던파)

Copy link

@hanjo8813 hanjo8813 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants