TDD 연습 프로젝트 2 - 멤버십 등록 API 구현 (Membership Repository)

zunzero·2022년 9월 5일
0

스프링, JPA

목록 보기
10/23

멤버십 등록 API

요구사항

  • 나의 멤버십 등록 API
    - 기능: 나의 멤버십을 등록합니다.
    • 요청: 사용자 식별값, 멤버십 이름, 포인트
    • 응답: 멤버십 ID, 멤버십 이름

Repository 계층 개발

TDD를 위해선 Repository -> Service -> Controller 순으로 구현해 나아가야 한다.
Controller는 Service를, Service는 Repository를 의존하기 때문에, 의존 관계에 가장 하위층인 Reposity를 먼저 구현하는 것이다.

우선 Membership Repository 에 대한 test를 먼저 작성할 것이다.

위의 코드를 먼저 작성했는데, 우선 컴파일 에러부터 만나게 될 것이다.
TDD는 컴파일 에러를 자주 만나고, 해당 에러를 해결해나가며 코드를 작성하는 방식인 것 같다.
왜 컴파일 에러가 날까...

당연하게도 우린 MembershipRepository 클래스를 작성하지 않았기 때문이다.
따라서 해당 에러를 해결하기 위해 우리는 MembershipRepository를 아래와 같이 작성하면 된다.

또, 또, 또, ... 컴파일 에러를 해결하기 위해 우린 Membership 클래스를 작성하면 된다.

이렇게 하고도 Test는 실패한다.
우선 Membership 엔티티가 jpa가 관리하는 형식이 아니기 때문에 @Entity 어노테이션을 붙여주어야 하고, 테스트 컨텍스트 생성을 위한 @DataJpaTest 어노테이션도 필요하다.

따라서 최종적으로 우리는 다음과 같이 코드를 작성할 수 있고 테스트는 성공하게 된다.

테스트 성공을 의미하는 초록불은 언제나 좋고 마음이 편안하다.
반면 실패를 의미하는 빨간불은,,, 언제나 불쾌하고 불편하고 찝찝하다.

멤버십 등록 테스트

멤버십 등록과 관련한 테스트 코드를 다음과 같이 작성하였다.
어마무시하게 많은 컴파일 에러가 발생했다.

이러한 컴파일 에러를 해결하는 과정을 통해 우리는 또 한 번 테스트를 성공시키면 된다.

작성된 테스트 코드 정보를 참고해, Membership 엔티티를 다음과 같이 수정하였고, 테스트는 성공적으로 통과했다.

membershipName의 정보는 '네이버', '라인', '카카오' 3가지를 사용할 것이기 때문에 Enum 타입으로 등록해두면 더 쉬울 것 같다.
따라서 테스트 코드와 엔티티 코드를 다음과 같이 수정하겠다.

멤버십 중복 확인용 테스트

멤버십이 중복으로 등록되었는지 확인하기 위해, userId와 MembershipType으로 DB에서 검색해보는 기능을 구현해야 한다.
따라서 다음과 같은 테스트 코드를 작성하였고, 컴파일 오류 해결을 위해 MembershipRepository를 업데이트 하였다.

테스트 또한 역시나 통과하였다.

기타

아래에는 이번 포스팅을 하면서 곁가지로 작성해놓는 것들이다.
자세한 내용은 따로 포스팅할 기회가 되면 포스팅할 것이다.

@Enumerated(EnumType.STRING)

Enumtype을 사용할 때, 우리는 반드시 해당 어노테이션을 사용해야 한다.
기본 설정은 @Enumerated(EnumType.ORDINAL) 인데, 이는 데이터베이스에 Enumtype의 순서를 저장하기 때문이다.
예를 들어 Enumtype을 NAVER, LINE, KAKAO 순으로 저장했다고 하자.
만약 이 떄 Enumtype을 NAVER, TOSS, LINE, KAKAO로 변경한다면 문제가 발생한다.
순서가 LINE은 기존에 2번이었는데, TOSS가 2번으로 바뀌게 되면서 기존 DB에 담긴 데이터와 추가로 DB에 담기는 데이터 간에 혼동이 발생한다.
어떤 데이터가 LINE 관련인지, TOSS 관련인지 알 길이 없다.
따라서 문자 그대로를 저장하는 @Enumerated(EnumType.STRING) 어노테이션을 반드시 사용해야 한다.

Builder 패턴

빌더 패턴은 GoF 디자인 패턴의 생성자 패턴 중 하나이다.
생성자를 사용하게 되면, 당장 값이 없는 속성에는 null 값을 넣어야 하거나, 따로 생성자를 만들어두어야 하는 불편함이 있다.
setter를 사용하면 된다고 할 수 있지만, setter는 협업 시 위험하다.
언제 데이터가 바뀌었는지 명시적으로 알 수 없어, setter는 열어두지 않고 닫아두고 사용하는 편이다.
아무튼 그래서 @Builder가 꿀이다.

@DataJpaTest, @SpringbootTest

나는 우선 Spring-data-jpa에 대한 사용법이나 원리 같은 것들을 잘 모르고, 순수 jpa만을 사용해왔다.
@Repository 어노테이션을 붙여서, EntityManager 클래스를 주입해서 직접 메서드를 하나하나 작성하는 아래와 같은 방식 말이다.

그래서 해당 Repository 클래스 또한, 위와 같은 방법으로 테스트를 진행해보았으나, 테스트에 실패했다.

UnsatisfiedDependencyException at AutowiredAnnotationBeanPostProcessor.java:659

에러 문구는 대략 위와 같았다.
뭔가 의존성 주입이... 문제가 생긴 것 같았다.

그래서 내가 원래 테스트에 사용했던 어노테이션인 @SpringbootTest로 @DataJpaTest를 치환해서 테스트를 돌렸더니 성공하게 되었다.

이에 대한 원인은 뭘까???
한 번 적어 보세요... 구글링 열심히 하시고...
우선 나는 다음 챕터로 !!!

profile
나만 읽을 수 있는 블로그

0개의 댓글