[F-Lab 모각코 챌린지 37일차] Repository test

부추·2023년 7월 7일
0

F-Lab 모각코 챌린지

목록 보기
37/66

TIL

  1. 프로젝트 아이디어 선정!
  2. @DataJpaTest



1. 프로젝트 아이디어 생각!!

사실 크게 하고 싶은 프로젝트는 없었는데, "실제 서비스할 것을 염두에 두고 프로젝트를 시작하면 좋다"라는 말을 들었다. 생각해보니 저 취업하려고 포폴에 넣으려고 플젝 시작했어요ㅋ 보다는 실생활에서 이러이러한걸 느꼈고, 이러이러한걸 해결해보고 싶어서 이러이러한 프로젝트를 시작해 보았습니다. 라는게 더 먹힐 것 같긴 했다.

1) 레시피 작성 및 공유 플랫폼

요리 레시피를 작성하고 공유할 수 있는 플랫폼

  • 사용자는 공유하고자 하는 요리 레시피의 각 단계와 그에 맞는 설명과 사진을 추가할 수 있습니다.

  • 소요 시간, 필요 재료, 음식 종류 등의 기본 정보가 필요합니다.

  • 각 레시피 단계 단위로 댓글을 달 수 있습니다. (이용자들의 추가 팁, 제품 추천 등)

  • 좋아요, 북마크, 후기 기능이 있습니다. 후기에 별점과 키워드를 추가할 수 있습니다. (ex.간단한/자극적인/건강한/유용한)

  • 레시피 작성자와 후기 작성자의 별점, 키워드, 요리 종류, 소요 시간 등을 기준으로 레시피를 검색하는 것이 가능합니다.

  • 레시피 작성자가 지정한 재료를 쿠팡 같은 커머스 사이트와 연결하는 것도 좋은 아이디어인듯?


2) 농수산물 공구 플랫폼

수산물 농가-소비자를 다이렉트로 이어주는 플랫폼! 농수산물의 공급/수요 불균형을 해소하고, 농가와 소비자 모두 만족할 만한 가격으로 상품을 거래합니다.

  • 농가로 등록된 생산자가 생산 예상 수량과 가격, 마감 날짜 및 시간을 정해두고 폼을 오픈하면, 소비자가 최소 요구 금액/수량 이상의 상품을 공구 형식으로 구매합니다.

  • 농가는 정기 공구 폼을 오픈할 수 있고, 소비자 역시 이를 구독할 수 있습니다.

  • 마감 시간이 얼마 남지 않았을 때 혹은 공구 수량이 많이 남지 않았을 때 타임 딜 세일 같은 기능을 도입할 수도 있습니다.

  • 사용자가 지정한 특정 키워드가 포함되어 있으며 + 설정한 가격 이하의 공구가 떴을 때 알람을 보낼 수도?

  • 농가 소개, 공구 항목 소개, 그리고 후기 기능이 존재합니다.


3) BOJ 국영수 버전

중고등학생들의 문제풀이 사이트. BOJ 국영수탐구 버전입니다.코딩테스트 문제,해법,질문들은 BOJ/리트코드 등에 집약되어있는 반면 의무교육과정의 문제,해법,질문들은 그렇지 않다는 것에서 나온 아이디어입니다.

  • 수능이나 모의고사 기출이 기본적으로 업로드 되어있고, 학원 같은 교육기관, 출판사, 혹은 이용자인 학생 본인들이 제작한 문제를 업로드할 수 있습니다.

  • 문제별로 질문 게시판이 존재합니다. BOJ의 질문 게시판과 유사합니다.

  • 문제별로 해답 게시판도 존재하는데, 학생들이 원하는 경우 자신의 해결법을 공유할 수 있습니다. (정답을 맞춰야 해답 게시판 열람 가능)

  • 과목별, 과목 안에서는 단원별(혹은 개념별) 분류가 존재합니다. (BOJ 알고리즘 분류)

  • 출판사나 학원 입장에선 자신이 제작한 문제를 업로드하고 학생들이 해당 문제를 다운받은 수만큼 수익을 올릴 수 있습니다.

  • 학생들은 네이버 웹툰의 [쿠키] 같은 개념으로 문제 다운로드권을 구매해서 출판사, 혹은 학원들이 업로드한 문제를 사이트 내 재화로 구매할 수 있습니다.


1번은 메모장에 1번 2번 해서 하나하나 글자로 저장하는 내 귀찮음 때문에, 2번은 우리 가문(?)의 생업에 영감을 받아, 3번은 사교육 격차 해소(ㅋㅋ)를 동기로 떠올려본 주제이다. 뭐가 적절할지, 각 프로젝트에 어떤 기능을 붙일 수 있고 그를 위해 공부해야하는 것이 무엇인지는 멘토님과 얘기하다보면 나오겠지..




2. Repository 테스트 코드

들어가기 전에, Spring에서 인터페이스@Component, @Repository 등의 빈 등록용 어노테이션을 붙일 필요가 없다는 얘기를 들었다. 더불어 JpaRepository<T,ID>를 extends한 레포지토리 인터페이스 역시 @Repository를 붙일 필요가 없다는 얘기를 들어버렸다.
이것은 마치.. @RequestBody로 사용자 요청을 받는 DTO에 @Setter을 쓸 필요가 없다는 얘기를 들었을 때와 같은 충격.. (인터페이스는 인스턴스 생성이 안되니 구현체가 없으면 @Component가 있어도 실제 빈으로 등록되지 못하는게 아닐까~ 생각하긴 함.)

Spring에서 인터페이스와 그 구현이 있다면 @Component(또는 @Service, @Repository 등과 같은 다른 특수 어노테이션)로 구현 클래스에만 어노테이션을 달면 충분합니다. 인터페이스 자체에는 특정 어노테이션이 필요하지 않습니다. 또한, Spring Data JPA에서 JpaRepository를 확장하는 인터페이스에는 @Repository 어노테이션이 필요하지 않습니다. @Repository는 클래스가 저장소의 역할을 수행하고 예외를 반환할 수 있음을 나타내는 데 사용되는 마커 주석입니다.

그래서 일단 이전에 했던 프로젝트 domain 패키지의 Repository 인터페이스를 확인해보니 어노테이션을 안달아놨다. 아마 깜빡했던 것 같은데..

// 휑~
public interface UrlRepository {
    List<ShortenUrl> findAll();
    Optional<ShortenUrl> findByShortenUrl(String shortenUrl);
    ShortenUrl save(ShortenUrl shortenUrl);
}

아무튼, 그렇더라도.. 일반적으로 리포지토리 인터페이스에 @Repository를 추가하여 역할을 명시적으로 전달하고 해당 어노테이션이 제공하는 스프링 repository 특정 예외 제공 등의 기능을 이용하기 위해


@DataJpaTest는 JPA Repository 테스트를 위해 JPA 관련한 테스트 자동설정을 해주는 어노테이션이다. 기본적으로 포함된 H2 데이터베이스를 사용하지만, 필요한 경우 다른 DB로 구성할 수 있고, @Entity 클래스를 스캔하여 테스트 중 엔티티 클래스를 사용할 수 있도록 하고, @Test 메소드 단위로 트랜잭션-롤백을 수행하고, 테스트 과정 중 수행되는 sql문을 출력해주고..헥헥..

어노테이션 설명을 보자!

Annotation for a JPA test that focuses only on JPA components.
Using this annotation will disable full auto-configuration and instead apply only configuration relevant to JPA tests.

(같은 얘기다)


본격적으로 Repository 테스트를 작성하기 전, @ActiveProfiles를 통해 테스트 환경에서 사용할 spring profile을 지정해야 한다.

현재 프로젝트에서 url 엔티티를 저장할 구현체로 3개를 두고 있는데, 난 아래의 JPA를 통해 구현된 Repository를 테스트 할 것이다.

@Repository
@Profile("jpa")
public interface UrlJpaRepository extends JpaRepository<ShortenUrl, String> {
    Optional<ShortenUrl> findByShortenUrl(String shortenUrl);
}

사용하는 profile은 "jpa"이다. 테스트 클래스에 그대로 적용시켜준다. 사용할 JpaRepository 클래스도 @Autowired 해주었다.

@DataJpaTest
@ActiveProfiles(profiles = "jpa")
public class UrlRepositoryTest {
	@Autowired
    private UrlJpaRepository urlJpaRepository;
}

그리고 이제 시작! 테스트할 로직은, 1) 엔티티 객체가 세이브되었는지 확인, 2) 세이브 된 객체의 초기값이 잘 설정되었는지 확인 이다.

1) 세이브 확인

@DisplayName("저장된 ShortenUrl 검색 테스트")
@Test
public void saveTest() {
    String original = "https://test.com";
    String shorten = ShortenUrl.generateShortenUrl();

    urlJpaRepository.save(ShortenUrl.builder()
            .originalUrl(original)
            .shortenUrl(shorten)
            .build());

    Assertions.assertNotNull(urlJpaRepository.findByShortenUrl(shorten));
}

2) 초기값 확인

@DisplayName("shortenUrl 초기값 세팅 테스트")
@Test
public void myTest() {
    String original = "https://test.com";
    String shorten = ShortenUrl.generateShortenUrl();

    urlJpaRepository.save(ShortenUrl.builder()
            .originalUrl(original)
            .shortenUrl(shorten)
            .build());

    ShortenUrl found = urlJpaRepository.findByShortenUrl(shorten).orElseThrow();
    Assertions.assertEquals(original,found.getOriginalUrl());
    Assertions.assertEquals(shorten,found.getShortenUrl());
    Assertions.assertEquals(0,found.getRequestedNumber());
}

근데 이 테스트코드는 내가 짠 로직에 대한 검증이라기보단 JPA 동작 자체를 검증하는 테스트인데.. @DataJpaTest 자체가 테스트로써 유의미하게 작용이 될까? 일단 안하는 것 보다는 낫다는 생각이지만..



REFERENCE

https://kim-jong-hyun.tistory.com/134

https://velog.io/@kshired/Spring-%EC%99%9C-JPARepository%EB%8A%94-Repository%EA%B0%80-%ED%95%84%EC%9A%94-%EC%97%86%EC%9D%84%EA%B9%8C-deep-dive-%ED%95%B4%EB%B3%B4%EA%B8%B0

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글