[4기 홍혁준] Mission 1, 3 PR 제출합니다#268
[4기 홍혁준] Mission 1, 3 PR 제출합니다#268hongdosan wants to merge 19 commits intoprgrms-be-devcourse:HyuckJuneHongfrom
Conversation
Shin-Jae-Yoon
left a comment
There was a problem hiding this comment.
혁준님 고생하셨습니다 ~! 사실 리뷰보단 질문의 장이 되어버린 것 같네요 ㅋ-ㅋ
| @Configuration | ||
| @EnableJpaAuditing | ||
| public class JpaConfig { | ||
| } |
There was a problem hiding this comment.
(질문) SpringbootJpaWeeklyMission에 @EnableJpaAuditing을 추가한 것이 아닌 따로 JpaConfig를 만드셨는데, 여기에는 어떤 설정들이 추가될 수 있나요 ??
There was a problem hiding this comment.
QueryDSL 설정이 추후에 추가될 수 있다고 생각했습니다 ㅎㅎ
|
|
||
| @Getter | ||
| public class DuplicateException extends RuntimeException { | ||
| private ErrorResult errorResult; |
There was a problem hiding this comment.
이 부분과 this.errorResult 부분이 sonarLint에서 밑줄이 나왔던 것 같은데
반드시 필요한 부분인가요 !?
There was a problem hiding this comment.
나중에 ExceptionHandler 처리할 때, 꺼내서 확인해보는 상황이 필요할 때가 있었습니다!
|
|
||
| @Getter | ||
| public class EntityNotFoundException extends RuntimeException { | ||
| private ErrorResult errorResult; |
| import org.springframework.http.HttpStatus; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor(access = AccessLevel.PRIVATE) |
There was a problem hiding this comment.
(질문) 이 부분은 @requiredargsconstructor가 아닌 @AllArgsConstructor(access = AccessLevel.PRIVATE)로 하신 이유가 있을까요 ??
There was a problem hiding this comment.
이유가 있다기보다! Required를 해도 모든 필드에 대해 생성자가 생길테니, 크게 생각하지 않은 부분입니다!
|
|
||
| return members.stream() | ||
| .map(MemberSimpleResponse::toDto) | ||
| .toList(); |
There was a problem hiding this comment.
(복습) Stream.toList() vs Stream.collect(toList()) 에 대해서 복습 한번 하고 가면 좋을 것 같슴다 ~!
There was a problem hiding this comment.
한 번 더 공부하라고... 리뷰까지 남겨주시는.. 흑흑
| public interface MemberRepository extends JpaRepository<Member, Long> { | ||
| Optional<Member> findByEmail(String email); | ||
|
|
||
| boolean existsByEmail(String email); |
There was a problem hiding this comment.
(복습) existsBy~ 의 쿼리가 어떤식으로 날라가는지 복습해보면 좋을 것 같슴다 ~!
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class OrderItem { | ||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) |
There was a problem hiding this comment.
현재 MySQL을 사용하는 상황인지 궁금함니다
| private Address(String street, String detail) { | ||
| this.street = street; | ||
| this.detail = detail; | ||
| } |
There was a problem hiding this comment.
이 부분은 저도 헷갈리는데, 파라미터 개수가 3개보다 작은 경우 Builder를 쓰지 않는 것이 낫다고는 하던데
가독성, 통일성을 챙기는게 나을지, 위 규칙을 지킬지 생각해보면 좋을 것 같아용
| @CreatedDate | ||
| @Column(name = "created_at", length = 20, nullable = false, updatable = false) | ||
| protected LocalDate createdAt; |
There was a problem hiding this comment.
LocalDate 타입에 length 조건을 추가한 이유가 있나요? 또 protected로 선언한 이유가 궁금합니다!
There was a problem hiding this comment.
앗 length는 생각없이 넣었네요!
protected로 선언한 이유 : BaseTimeEntity는 상속해서 사용하기 때문에 protected로 선언해봤습니다!
희빈은 의견은 어떤가요??
| package kr.co.springbootjpaweeklymission.global.common; | ||
|
|
||
|
|
||
| import jakarta.persistence.Column; |
There was a problem hiding this comment.
package와 import 사이 줄바꿈 1번 or 2번으로 컨벤션 통일하면 좋을 것 같아요!
| INVALID_PARAMETER("파라미터 값이 유효하지 않습니다.", HttpStatus.BAD_REQUEST), | ||
| ; |
There was a problem hiding this comment.
오 이런식으로 쓰는게 새로운 값 추가할 때 더 좋을 것 같네요! 굿굿
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "item_id", length = 4, nullable = false, unique = true) | ||
| private Long itemId; |
There was a problem hiding this comment.
@Id가 충분히 pk로써 의미를 가지고 있고, 잘 통용되고 있다고 생각하는데 추가로 @Column 붙이는 이유는 더 명시적이고 통일성을 위함일까요?
추가로 여기서 Long 타입에 length 조건을 걸어준 이유가 있을까요?!
There was a problem hiding this comment.
사실상 name 속성만 있어도 될 것 같네요 ㅎㅎ
@column을 붙인 이유는 희빈님 말 그대로 더 명시적이고 통일성을 위함입니다!
| isEmail(putRequest.getEmail()); | ||
| isCellPhone(putRequest.getCellPhone()); |
There was a problem hiding this comment.
메서드 네이밍만으로는 해당 이메일/번호의 중복을 체크하는 메서드인지 파악하기 어려운 것 같습니다
| @PostMapping | ||
| public ResponseEntity<Long> createMember(@RequestBody @Validated MemberPutRequest putRequest) { |
There was a problem hiding this comment.
메서드 파라미터 검증에 @Valid가 아닌 @Validated를 사용하신 이유가 있을까요?
There was a problem hiding this comment.
예전이 스터디 했던 팀원분이 @validated가 더 좋다. 라는 말을 들었어서 사용했는데, 지금 다시 찾아보니, 딱히 좋은 점을 찾지 못하겠네요.
무작정 말만 듣고 적용했던 과거의 나에게 반성문을 쓰도록 하겠습니다 ㅠ
| assertThat(actual.getModifiedAt()).isEqualTo(LocalDate.now()); | ||
| } |
There was a problem hiding this comment.
modifiedAt과 LocalDate.now()이 시간적 차이가 발생하는 경우는 없을까요?
There was a problem hiding this comment.
LocalDateTime이 아닌 LocalDate이기 때문에, 괜찮다고 생각했습니다!
근데 만약 23시 59분에 테스트를 돌렸다면..? 이점을 고려해봐야겠네요 ㅠ
| @Test | ||
| @CsvSource(value = {"", "ex2@naver.com", "ex3@naver.com"}) |
There was a problem hiding this comment.
@CsvSource는 사용하지 않고 있는 것 같습니다!~
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
|
||
| @DataJpaTest | ||
| @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) |
There was a problem hiding this comment.
메서드에 @DisplayName을 적용하면 불필요한 부분이라고 생각하는데, 추가하신 이유가 있으실까요?!
| assertThat(savedMember.getAddress().getStreet()).isEqualTo(member.getAddress().getStreet()); | ||
| assertThat(savedMember.getAddress().getDetail()).isEqualTo(member.getAddress().getDetail()); |
There was a problem hiding this comment.
Member 엔티티에 getStreet, getDetail 메서드를 구현하신걸로 기억합니다.!
|
|
||
| @Slf4j | ||
| @RestControllerAdvice | ||
| public class NotValidExceptionHandler { |
There was a problem hiding this comment.
저도 유사하게 exceptionhandler를 사용했었는데 하나의 클래스에서 한 것이 아닌 여러 클래스로 나눠서 처리한 이유가 궁금합니다!
There was a problem hiding this comment.
사실 한 프로젝트당 하나의 ControllerAdvice만 관리하는 것이 좋은데, 객체를 분리하는게 습관이 되어서 고쳐보도록 하겠습니다 ㅠ
| import static org.mockito.BDDMockito.given; | ||
|
|
||
| @ExtendWith(MockitoExtension.class) | ||
| class MemberServiceUnitTest { |
There was a problem hiding this comment.
mock을 너무 많이 사용하게 되는 부분은 통합으로 빼서 테스트를 돌렸습니다 ㅎㅎ
| @Entity | ||
| @Table(name = "tbl_orders") | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class Order { |
There was a problem hiding this comment.
Order와 OrderItem은 어떤 기준으로 패키지를 분리하셨나요?
패키지 전체가 엔티티기준으로 분리된 건가요? 아님 도메인으로 분리하신건가요??
There was a problem hiding this comment.
저는 둘다입니다. 처음에는 도메인 기준으로 분리를 했지만, orderItem을 어디에서 관리하는게 좋을 지 고민하다가, 도저히 고를 수가 없어서 따로 뺐습니다! 추후에 개발을 더 진행한다면 또 변경될 수 있는 부분이라고 생각합니다 ㅎ
ymkim97
left a comment
There was a problem hiding this comment.
과제 하느라 고생하셨습니다!!!
조금 늦게 달아서 다른 분들과 겹치거나 이미 잘 해주셔서 많지 않습니다 ㅠ.ㅠ
| runtimeOnly 'com.h2database:h2' | ||
|
|
||
| //MySQL | ||
| runtimeOnly 'com.mysql:mysql-connector-j' |
There was a problem hiding this comment.
Dependency를 이렇게 나누니까 정말 좋은거 같아요! 배워갑니다 >.<
| @@ -0,0 +1,17 @@ | |||
| package kr.co.springbootjpaweeklymission.item.domain.entity; | |||
|
|
|||
| import jakarta.persistence.*; | |||
There was a problem hiding this comment.
와일드 카드 import는 가급적 쓰지 않는 것이 좋다고 합니다!
아마 인텔리제이가 자동으로 이렇게 만들어줬을거고 저도 순간 잊어서 이렇게 했지만🥺...
세팅에서 예방할 수 있습니다!
| @Table(name = "tbl_orders") | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| public class Order { | ||
| @Id |
There was a problem hiding this comment.
오 저도 Order와 OrderItem은 어떤 기준으로 패키지를 분리하셨는지 궁금합니다!
코드를 작성하면서 궁금했는데 Order, OderItem, Item과 같은 연관관계가 있으면 어떻게 패키지를 분리하는 것이 좋을까요?
There was a problem hiding this comment.
OrderItem 은 사실 어느 곳에 들어가도 상관없을 것 같습니다! 하지만 저 같은 경우엔 둘 중 어디에 넣을 지 계속 고민하다가 분리를 했는데, 추후에 변경될 수도 있는 부분입니다 ㅎ 만약 넣는다면 책임이 더 많은 order 패키지에 넣을 것 같네요 ㅎ
📌 과제 설명
고객(Member) 엔티티를 생성하고 그에 따른 CRUD 기능 테스트 구현했습니다.
고객, 주문, 상품 사이의 연관관계를 설정해보았습니다.
👩💻 요구 사항과 구현 내용
✅ PR 포인트 & 궁금한 점
현업에서의 mock Test에 대해 궁금합니다.
현업에서의 Controller Test에 대해 궁금합니다.