Skip to content

test(api): Phase 1 — 서비스 로직 단위 테스트 (10% → 30%) #164

@cocoyoon

Description

@cocoyoon

Context

테스트 인프라 구축(#163) 완료 후, 가장 큰 서비스 파일들의 핵심 경로를 커버하여 커버리지를 **10% → 30%**로 올린다.

대상 파일 (~120 tests)

파일 LOC 기존 테스트 신규 테스트 내용
domains/posts/service.rs 2,084 13 ~30 CRUD, 트랜잭션, 조회 필터링, 페이지네이션
domains/rankings/service.rs 597 0 ~15 랭킹 계산, 기간별 집계, 카테고리 필터
domains/solutions/service.rs ~320 0 ~10 생성, 메타데이터 추출, 어필리에이트 변환
domains/post_magazines/service.rs 402 0 ~10 매거진 CRUD, 세션 연결
domains/search/service.rs 392 0 ~10 검색 실행, 유사 검색, 인기/최근 검색
domains/feed/service.rs 365 0 ~10 홈 피드 조합, 트렌딩, 큐레이션
domains/categories/service.rs 349 0 ~8 카테고리 트리, 캐시, 기본값
domains/votes/service.rs 332 0 ~8 투표 생성/삭제, 중복 방지, 통계
domains/spots/service.rs 305 0 ~8 스팟 CRUD, 포지션 업데이트
domains/posts/dto.rs 758 2 ~15 유효성 검증 엣지 케이스, 기본값

테스트 패턴

// MockDatabase로 쿼리 결과 설정 → 서비스 함수 호출 → 결과 검증
let db = MockDatabase::new(DatabaseBackend::Postgres)
    .append_query_results([[post_model()]])
    .into_connection();
let result = get_post_by_id(&db, post_id).await;
assert!(result.is_ok());

// 에러 경로
let db = MockDatabase::new(DatabaseBackend::Postgres)
    .append_query_results([Vec::<post::Model>::new()])
    .into_connection();
let result = get_post_by_id(&db, post_id).await;
assert!(matches!(result, Err(AppError::NotFound(_))));

작업 목록

posts 도메인 (~30 tests)

  • create_post_without_solutions — 정상 생성, 유효성 실패
  • create_post_with_solutions — 솔루션 포함 생성, 트랜잭션 롤백
  • list_posts — 페이지네이션, 필터(카테고리, 아티스트, 그룹), 빈 결과
  • get_post_detail — 정상 조회, NotFound, 좋아요/저장 상태 포함
  • update_post — 소유권 검증, 필드 업데이트
  • delete_post — 정상 삭제, 권한 없음
  • create_try_post — VTON 플로우
  • list_tries / count_tries — 페이지네이션

rankings 도메인 (~15 tests)

  • get_rankings — 기간별(일/주/월), 빈 결과
  • get_category_rankings — 카테고리 필터
  • get_my_ranking_detail — 사용자 포지션, 미등록 사용자

solutions 도메인 (~10 tests)

  • create_solution — 정상 생성, AI 분석 트리거
  • list_solutions_by_spot_id — 투표 정보 포함
  • extract_metadata — 외부 서비스 호출 mock
  • convert_affiliate_link — 라쿠텐 변환

나머지 도메인 (post_magazines, search, feed, categories, votes, spots)

  • 각 서비스의 CRUD happy path + 주요 에러 경로

DTO 유효성 검증 (~15 tests)

  • CreatePostDto — 필수 필드 누락, 길이 제한
  • UpdatePostDto — 부분 업데이트
  • 기타 DTO의 serde roundtrip 및 validation 엣지 케이스

완료 조건

cargo tarpaulin --lib --exclude-files 'src/entities/*' --fail-under 30
  • scripts/pre-push.sh--fail-under30으로 업데이트

Depends on

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions