Skip to content

Conversation

@1winhyun
Copy link
Member

@1winhyun 1winhyun commented Dec 22, 2025

Related issue 🛠

  • closed #

작업 내용 💻

피드와 관련한 테스트 코드를 작성했습니다.
테스트 코드는 단위 테스트로 진행하여 각 메서드 별로 정상적으로 동작하는 것을 테스트 코드로 작성했습니다.
특정 메서드의 경우 예외처리와 관련한 코드를 추가적으로 작성했습니다.
지속적으로 사용되는 Feed, User, Comment 등 엔티티의 생성 빌더 로직은 Fixture로 따로 분리해 구현해 사용했습니다.

  • FeedUsecase 테스트 코드를 작성했습니다.
  • FeedRepository 테스트 코드를 작성했습니다.
  • CommentRepository 테스트 코드를 작성했습니다.
  • ReactionRepository 테스트 코드를 작성했습니다.
  • LinkedUserRepository 테스트 코드를 작성했습니다.

스크린샷 📷

같이 얘기해보고 싶은 내용이 있다면 작성 📢

Summary by CodeRabbit

릴리스 노트

  • Tests

    • 피드, 댓글, 반응 등 도메인 전반에 걸친 단위 및 통합 테스트 대폭 추가
    • 저장소·서비스·유즈케이스 테스트 보강 및 테스트 픽스처/유틸리티 추가로 작성·유지성 향상
    • 컨테이너 기반 통합 검증을 위한 테스트(실행 확인, DB 연동 검증) 추가
  • Chores

    • JUnit 5 및 Testcontainers 기반 테스트 인프라 도입(메이저 DB 이미지 지원 포함)
    • 테스트 전용 설정 및 테스트 프로파일(테스트용 애플리케이션 설정) 개선
    • 알림 엔티티에 MongoDB 감사 필드 반영 및 관련 인프라 정비

✏️ Tip: You can customize this high-level summary in your review settings.

@1winhyun 1winhyun self-assigned this Dec 22, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 22, 2025

Walkthrough

Gradle에 JUnit5 및 Testcontainers 테스트 의존성을 추가하고, Notification 엔티티를 MongoBaseEntity로 전환했으며, MySQL Testcontainers 설정과 광범위한 단위·통합 테스트 및 테스트 픽스처들을 추가했습니다.

Changes

Cohort / File(s) 변경 요약
빌드 및 의존성
\build.gradle``
JUnit 5(org.junit.jupiter:junit-jupiter:5.8.1), Spring Boot 테스트, Testcontainers(공통, MySQL, MongoDB) 및 Testcontainers JUnit 어댑터 등을 테스트용으로 추가
엔티티 & 공통베이스
\src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java`, `src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java``
NotificationBaseEntity에서 MongoBaseEntity로 변경; Mongo 전용 어노테이션(@Document, @Id) 도입 및 MongoBaseEntity(생성/수정일 자동화) 신규 추가
테스트 설정 / 리소스
\src/test/java/leets/leenk/config/MysqlTestConfig.java`, `src/test/java/leets/leenk/config/TestContainersTest.java`, `src/test/resources/application-test.yml``
MySQL Testcontainers 빈(@ServiceConnection) 추가, 컨테이너 검증 테스트 추가, 테스트용 application-test.yml(hibernate 설정) 추가
리포지토리 레벨 테스트
\src/test/java/leets/leenk/domain/feed/domain/repository/*RepositoryTest.java``
FeedRepositoryTest, CommentRepositoryTest, LinkedUserRepositoryTest, ReactionRepositoryTest 등 데이터 JPA 테스트 추가(타임스탬프/페이징/정렬 검증 포함)
서비스·유스케이스 테스트
\src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java`, `src/test/java/leets/leenk/domain/feed/domain/service/*ServiceTest.java``
FeedUsecase에 대한 광범위한 Mockito 기반 테스트 및 여러 서비스 유닛 테스트 추가(예외/권한/알림/연관 엔티티 상호작용 검증)
테스트 픽스처 유틸리티
\src/test/java/leets/leenk/domain/feed/test/*TestFixture.java``
Feed, Comment, Media, Reaction, User, LinkedUser 등의 테스트 픽스처(생성 헬퍼) 추가

Sequence Diagram(s)

(생략)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • jj0526
  • hyxklee
  • dalzzy

Poem

🐇 저는 작은 토끼, 코드밭을 뛰네,
테스트 씨앗 심어 컨테이너 안에,
몽고로 바뀐 나무에 시간 달아두고,
픽스처 꽃 피워 모의해 보았네,
빌드가 초록 불 켜지면 당근 꿀꺽! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 'LNK-44 피드 테스트 코드 작성'으로 변경 사항의 주요 내용(피드 관련 테스트 코드 작성)을 명확하게 설명하고 있습니다.
Description check ✅ Passed PR 설명이 필수 섹션을 대부분 포함하고 있으나, 'Related issue' 섹션의 이슈 번호 미작성과 '스크린샷'/'같이 얘기해보고 싶은 내용' 섹션이 미완성된 상태입니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch LNK-44-Leenk-피드-테스트-코드-작성

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java (1)

13-13: 접근 제한자를 PROTECTED로 변경 권장

하위 엔티티인 Notification@NoArgsConstructor(access = AccessLevel.PROTECTED)를 사용하고 있습니다. 일관성과 엔티티 설계 모범 사례를 위해 기본 클래스에서도 동일하게 PROTECTED 접근 제한자를 사용하는 것을 권장합니다.

🔎 제안하는 수정
+import lombok.AccessLevel;
+
 @Getter
 @SuperBuilder
-@NoArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
 public abstract class MongoBaseEntity {
src/test/java/leets/leenk/config/TestContainersTest.java (1)

23-31: 테스트 검증 로직이 적절합니다.

컨테이너 상태 및 데이터베이스명 검증이 명확하게 구현되어 있습니다.

💡 선택적 개선사항: System.out.println 대신 로거 사용

디버깅 출력을 위해 System.out.println 대신 로거를 사용하는 것을 고려해보세요:

+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 @DataJpaTest
 @Import(MysqlTestConfig.class)
 @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
 @ActiveProfiles("test")
 class TestContainersTest {
+    private static final Logger log = LoggerFactory.getLogger(TestContainersTest.class);
 
     @Autowired
     private MySQLContainer<?> mysqlContainer;
 
     @Test
     void MySQL_컨테이너_정상_동작_테스트() {
         assertThat(mysqlContainer).isNotNull();
         assertThat(mysqlContainer.isRunning()).isTrue();
         assertThat(mysqlContainer.getDatabaseName()).isEqualTo("testdb");
 
-        System.out.println("MySQL Container JDBC URL: " + mysqlContainer.getJdbcUrl());
+        log.info("MySQL Container JDBC URL: {}", mysqlContainer.getJdbcUrl());
     }
 }
src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java (1)

60-60: 사용하지 않는 Logger를 제거하는 것을 고려하세요.

Line 60에 선언된 Logger가 테스트 코드 전체에서 사용되지 않습니다. 필요하지 않다면 제거하는 것이 좋습니다.

🔎 수정 제안
-    private static final Logger log = LoggerFactory.getLogger(FeedUsecaseTest.class);
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 268b0ac and 05cc746.

📒 Files selected for processing (17)
  • build.gradle
  • src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java
  • src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java
  • src/test/java/leets/leenk/config/MysqlTestConfig.java
  • src/test/java/leets/leenk/config/TestContainersTest.java
  • src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java
  • src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java
  • src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTextFixture.java
  • src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java
  • src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java
  • src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java
  • src/test/resources/application-test.yml
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: The LinkedUser entity in the Leenk-BE project has a unique constraint on the combination of feed_id and user_id columns (UniqueConstraint(columnNames = {"feed_id", "user_id"})), which requires explicit flush() calls after delete operations to prevent constraint violations during the delete-and-recreate pattern used in feed updates.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTextFixture.java
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: In the Leenk-BE project, the LinkedUser entity has DB unique constraints that require explicit flush() calls after deleteAllByFeed operations to prevent constraint violations when recreating the relationships immediately afterward.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTextFixture.java
🧬 Code graph analysis (6)
src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java (3)
src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java (1)
  • CommentTestFixture (7-16)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/LinkedUserTextFixture.java (1)
  • LinkedUserTextFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java (1)
src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java (1)
  • SuperBuilder (12-37)
src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java (1)
src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java (1)
  • Getter (11-21)
src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java (9)
src/main/java/leets/leenk/domain/feed/application/exception/CommentDeleteNotAllowedException.java (1)
  • CommentDeleteNotAllowedException (5-9)
src/main/java/leets/leenk/domain/feed/application/exception/FeedDeleteNotAllowedException.java (1)
  • FeedDeleteNotAllowedException (5-9)
src/main/java/leets/leenk/domain/feed/application/exception/FeedUpdateNotAllowedException.java (1)
  • FeedUpdateNotAllowedException (5-9)
src/main/java/leets/leenk/domain/feed/application/exception/SelfReactionNotAllowedException.java (1)
  • SelfReactionNotAllowedException (5-9)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java (1)
  • MediaTestFixture (7-18)
src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java (1)
  • CommentTestFixture (7-16)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
🔇 Additional comments (38)
src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java (2)

4-4: MongoDB 마이그레이션 확인 필요

Notification 엔티티가 JPA 기반 BaseEntity에서 MongoDB 기반 MongoBaseEntity로 마이그레이션되었습니다. 이 변경은 @Document 어노테이션과 일관성이 있습니다. 다만, MongoBaseEntity의 감사 기능이 제대로 동작하려면 @EnableMongoAuditing 설정이 필요합니다.

다음 사항을 확인해주세요:

  1. 기존 JPA 기반 알림 데이터의 마이그레이션 계획
  2. createDateupdateDate 필드가 기존 데이터와 호환되는지 확인
  3. MongoDB 감사 설정이 활성화되었는지 확인

Also applies to: 16-16


23-23: MongoDB에서 enum 필드 직렬화 적절히 구성됨

Spring Data MongoDB는 @Enumerated 어노테이션을 지원하지 않으므로 이를 제거한 변경은 정확합니다. MongoDB는 기본적으로 enum을 문자열로 직렬화하므로(enum 이름 사용), 이 동작은 기존 JPA의 @Enumerated(EnumType.STRING)과 동일합니다. 기존 데이터가 있다면 enum 이름이 변경되지 않았는지 확인하시기 바랍니다.

src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java (1)

11-21: MongoDB 감사 기능이 이미 활성화되어 있습니다. MongoConfig 클래스에서 @EnableMongoAuditing이 설정되어 있으므로, @CreatedDate와 @LastModifiedDate 어노테이션이 정상 작동합니다.

Likely an incorrect or invalid review comment.

src/test/resources/application-test.yml (1)

1-9: 테스트 설정이 적절합니다.

Hibernate의 create-drop DDL 전략과 SQL 로깅 설정이 테스트 환경에 적합하며, MySQL8Dialect 사용도 올바릅니다.

src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)

6-14: 테스트 픽스처 구현이 적절합니다.

Feed 엔티티 생성을 위한 간결하고 명확한 빌더 패턴 활용이 좋습니다.

src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)

5-13: 테스트 픽스처 구현이 적절합니다.

User 엔티티 생성을 위한 명확한 빌더 패턴 활용이 좋습니다.

src/test/java/leets/leenk/domain/feed/test/LinkedUserTextFixture.java (1)

8-13: 테스트 픽스처 구현이 적절합니다.

LinkedUser 엔티티 생성을 위한 명확한 빌더 패턴 활용이 좋습니다.

src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java (1)

7-15: 테스트 픽스처 구현이 적절합니다.

Comment 엔티티 생성을 위한 명확한 빌더 패턴 활용이 좋습니다.

src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)

7-14: 테스트 픽스처 구현이 적절합니다.

Reaction 엔티티 생성을 위한 명확한 빌더 패턴 활용이 좋습니다.

src/test/java/leets/leenk/config/TestContainersTest.java (1)

13-16: 테스트 설정이 적절합니다.

@DataJpaTest@Import를 통한 MySQL Testcontainer 구성이 올바르며, @AutoConfigureTestDatabase(replace = NONE)을 통해 실제 컨테이너 DB를 사용하도록 설정한 것이 적절합니다.

src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java (1)

7-17: 테스트 픽스처 구현이 적절합니다.

Media 엔티티 생성을 위한 테스트 픽스처가 잘 구현되었습니다. 고정된 테스트 데이터를 사용하여 일관된 테스트 환경을 제공합니다.

src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java (3)

41-68: 테스트 로직이 올바르게 구현되었습니다.

삭제된 댓글과 삭제되지 않은 댓글을 구분하여 조회하는 로직이 정확하게 테스트되었습니다. JPQL을 사용한 날짜 설정과 검증 로직이 적절합니다.


70-105: 테스트 로직이 올바르게 구현되었습니다.

피드별 댓글 조회 및 생성일자 내림차순 정렬 테스트가 잘 작성되었습니다. 삭제된 댓글 필터링과 다른 피드의 댓글 제외 로직이 정확하게 검증됩니다.


107-118: 헬퍼 메서드 구현이 적절합니다.

JPQL을 사용한 날짜 업데이트와 영속성 컨텍스트 관리 헬퍼 메서드가 테스트에 효과적으로 사용되고 있습니다.

src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java (2)

39-58: 테스트 로직이 올바르게 구현되었습니다.

피드와 사용자로 리액션을 조회하는 테스트가 정확하게 작성되었습니다. 리액션 ID와 카운트 검증이 적절합니다.


60-84: 테스트 로직이 올바르게 구현되었습니다.

특정 피드의 모든 리액션을 조회하는 테스트가 잘 작성되었습니다. 여러 사용자의 리액션이 올바르게 조회되는지 검증합니다.

src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java (3)

41-65: 테스트 로직이 올바르게 구현되었습니다.

피드에 연결된 사용자 목록 조회 테스트가 정확하게 작성되었습니다. 저장 순서대로 조회되는지 검증합니다.


67-105: 테스트 로직이 올바르게 구현되었습니다.

사용자가 태그된 피드 조회 테스트가 잘 작성되었습니다. 삭제된 피드를 제외하고 본인이 작성하지 않은 피드만 조회되는지 정확하게 검증합니다.


107-131: 피드별 연결 삭제 테스트가 올바르게 구현되었습니다.

deleteAllByFeed 후 flush를 명시적으로 호출하는 것이 적절합니다. LinkedUser 엔티티의 unique constraint로 인해 삭제 후 즉시 재생성하는 패턴에서 제약 조건 위반을 방지하기 위해 필요합니다.

Based on learnings, 이 구현은 프로젝트의 기존 패턴과 일치합니다.

src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java (5)

40-58: 기본적인 저장 및 조회 테스트가 올바르게 구현되었습니다.

Feed 엔티티의 저장과 조회, 그리고 User와의 관계가 정확하게 검증됩니다.


60-102: 차단 사용자 필터링 테스트가 올바르게 구현되었습니다.

페이지네이션과 차단 사용자 필터링, 삭제된 피드 제외 로직이 정확하게 테스트되었습니다. 날짜 기준 내림차순 정렬도 올바르게 검증됩니다.


140-164: 삭제되지 않은 피드 조회 테스트가 올바르게 구현되었습니다.

ID와 deletedAt 조건으로 피드를 조회하는 로직이 정확하게 검증됩니다.


166-208: 이전 피드 조회 테스트가 올바르게 구현되었습니다.

특정 시점 이후의 피드를 조회하면서 차단 사용자와 삭제된 피드를 필터링하는 로직이 정확하게 테스트되었습니다.


210-252: 다음 피드 조회 테스트가 올바르게 구현되었습니다.

특정 시점 이전의 피드를 조회하면서 차단 사용자와 삭제된 피드를 필터링하는 로직이 정확하게 테스트되었습니다.

src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java (13)

122-157: 피드 목록 조회 테스트가 올바르게 구현되었습니다.

차단 사용자 필터링과 미디어 매핑을 포함한 피드 조회 로직이 정확하게 테스트되었습니다. Mock 설정과 검증이 적절합니다.


159-194: 피드 상세 조회 테스트가 올바르게 구현되었습니다.

피드, 미디어, 연결된 사용자, 댓글을 모두 조회하는 로직이 정확하게 테스트되었습니다. BDDMockito의 then()을 사용한 검증이 적절합니다.


196-309: 피드 네비게이션 테스트가 포괄적으로 구현되었습니다.

이전/다음 피드 조회 로직과 null 파라미터 처리가 정확하게 테스트되었습니다. 두 테스트 모두 다양한 시나리오를 잘 커버합니다.


311-347: 피드 업로드 테스트가 올바르게 구현되었습니다.

피드 저장, 미디어 저장, 사용자 태그, 알림 생성이 모두 정확하게 테스트되었습니다. 각 서비스 호출이 올바르게 검증됩니다.


349-432: 리액션 테스트가 다양한 시나리오를 커버합니다.

자기 피드 리액션 금지, 기존 리액션 업데이트, 새 리액션 생성 시나리오가 모두 정확하게 테스트되었습니다. 예외 처리와 알림 로직 검증이 적절합니다.


434-457: 댓글 작성 테스트가 올바르게 구현되었습니다.

댓글 생성 및 저장 로직이 정확하게 테스트되었습니다.


459-489: 리액션 사용자 조회 테스트가 올바르게 구현되었습니다.

리액션 목록 조회 및 응답 매핑 로직이 정확하게 테스트되었습니다.


491-550: 피드 수정 테스트가 권한 검증을 포함하여 잘 구현되었습니다.

작성자가 아닌 경우 예외 발생과 미디어/연결 사용자 업데이트 로직이 정확하게 테스트되었습니다.


552-641: 다양한 피드 목록 조회 테스트가 올바르게 구현되었습니다.

내 피드, 다른 사용자 피드, 태그된 피드 조회 로직이 각각 정확하게 테스트되었습니다. 각 시나리오별 매핑 로직 검증이 적절합니다.


643-684: 사용자 조회 테스트가 올바르게 구현되었습니다.

전체 사용자 조회와 페이지네이션 조회 로직이 정확하게 테스트되었습니다.


686-726: 피드 삭제 테스트가 권한 검증을 포함하여 잘 구현되었습니다.

작성자 검증과 삭제 로직이 정확하게 테스트되었습니다. 권한이 없는 경우 예외 처리가 적절합니다.


728-771: 댓글 삭제 테스트가 권한 검증을 포함하여 잘 구현되었습니다.

작성자 검증과 삭제 로직이 정확하게 테스트되었습니다. 권한이 없는 경우 예외 처리가 적절합니다.


773-795: 피드 신고 테스트가 올바르게 구현되었습니다.

노션과 슬랙으로 신고 내용을 전송하는 로직이 정확하게 테스트되었습니다.

src/test/java/leets/leenk/config/MysqlTestConfig.java (1)

11-17: MySQL 8.0.41의 보안 취약점 고려하여 버전 업그레이드 검토 필요

MySQL 8.0.41은 유효한 버전이지만 여러 보안 취약점이 버전 8.0.0-8.0.41을 포함하는 범위에서 존재합니다. 이러한 취약점들은 높은 권한을 가진 공격자가 네트워크 접근을 통해 MySQL 서버를 손상시킬 수 있습니다. 테스트 환경이지만, 8.0.42, 8.0.43, 8.0.44 같은 더 최신 버전으로의 업그레이드를 검토하세요.

Comment on lines +44 to +45
testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

중복 의존성을 제거하세요.

Line 42와 Line 45에 spring-boot-starter-test가 중복 선언되어 있습니다. Line 45를 제거하세요.

🔎 중복 제거를 위한 제안
 testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
-testImplementation 'org.springframework.boot:spring-boot-starter-test'
 testImplementation 'org.springframework.boot:spring-boot-testcontainers'

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In build.gradle around lines 44 to 45, the dependency
'org.springframework.boot:spring-boot-starter-test' is declared twice (also
present at line 42); remove the duplicate declaration at line 45 so the project
only declares spring-boot-starter-test once, leaving the junit-jupiter
dependency intact.

// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

JUnit Jupiter 버전 업데이트를 권장합니다.

JUnit Jupiter 5.8.1은 2021년 9월 릴리스된 구버전입니다. JUnit 5 라인의 최신 안정 버전인 5.14.1 또는 현재 최신 버전인 6.0.1로 업그레이드하시기 바랍니다. 단, JUnit 6으로 업그레이드할 경우 Java 17 이상이 필요합니다.

🤖 Prompt for AI Agents
In build.gradle around line 44, the project pins JUnit Jupiter to 5.8.1 (old);
update the dependency to a recent stable release—replace testImplementation
"org.junit.jupiter:junit-jupiter:5.8.1" with testImplementation
"org.junit.jupiter:junit-jupiter:5.14.1" (or
"org.junit.jupiter:junit-jupiter:6.0.1" if you have Java 17+); ensure the
project Java compatibility in build.gradle
(sourceCompatibility/targetCompatibility or toolchain) matches the chosen JUnit
6 requirement if you pick 6.x.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java (3)

140-164: ID와 삭제 여부로 조회하는 테스트가 정확합니다.

삭제되지 않은 피드는 조회되고, 삭제된 피드는 조회되지 않는 로직이 올바르게 검증됩니다.

🔎 선택적 개선: 변수 명명 규칙

Line 149의 Deleted 변수명은 Java 관례상 소문자로 시작하는 것이 좋습니다:

-        Feed Deleted = feedRepository.save(FeedTestFixture.createFeed(null, me));
+        Feed deleted = feedRepository.save(FeedTestFixture.createFeed(null, me));

그리고 Line 153과 158에서도 동일하게 수정:

-        updateFeedDates(Deleted.getId(), base.plusMinutes(1), base.plusMinutes(2));
+        updateFeedDates(deleted.getId(), base.plusMinutes(1), base.plusMinutes(2));
-        Optional<Feed> deletedFeed = feedRepository.findByDeletedAtIsNullAndId(Deleted.getId());
+        Optional<Feed> deletedFeed = feedRepository.findByDeletedAtIsNullAndId(deleted.getId());

166-208: 이전 피드 조회 테스트의 타임스탬프 중복을 개선하면 좋겠습니다.

테스트 로직은 올바르지만, lines 184-185에서 feed1feed2가 동일한 생성 시각(base.plusMinutes(1))을 가지고 있습니다. 이는 데이터베이스가 일관된 정렬을 보장하지 않을 경우 테스트 결과가 비결정적이 될 수 있습니다.

타임스탬프를 다르게 설정하여 명확한 정렬 순서를 보장하는 것을 권장합니다.

🔎 제안: 타임스탬프 차별화
         updateFeedDates(feed1.getId(), base.plusMinutes(1), null);
-        updateFeedDates(feed2.getId(), base.plusMinutes(1), null);
+        updateFeedDates(feed2.getId(), base.plusMinutes(2), null);
         updateFeedDates(feedDeleted.getId(), base.plusMinutes(2), base.plusMinutes(4));
         updateFeedDates(feed3.getId(), base.plusMinutes(3), null);
         updateFeedDates(feedBlocked.getId(), base.plusMinutes(4), null);

그리고 삭제된 피드의 타임스탬프도 조정:

-        updateFeedDates(feedDeleted.getId(), base.plusMinutes(2), base.plusMinutes(4));
+        updateFeedDates(feedDeleted.getId(), base.plusMinutes(5), base.plusMinutes(6));

블록된 피드도 조정:

-        updateFeedDates(feedBlocked.getId(), base.plusMinutes(4), null);
+        updateFeedDates(feedBlocked.getId(), base.plusMinutes(7), null);

210-252: 다음 피드 조회 테스트의 타임스탬프 중복을 개선하면 좋겠습니다.

테스트 로직은 정확하지만, lines 228과 232에서 feed1feed3이 동일한 생성 시각(base.minusMinutes(10))을 가지고 있어, 정렬 순서가 비결정적일 수 있습니다.

🔎 제안: 타임스탬프 차별화
         updateFeedDates(feed1.getId(), base.minusMinutes(10), null);
         updateFeedDates(feed2.getId(), base.minusMinutes(20), null);
         updateFeedDates(feedDeleted.getId(), base.minusMinutes(30), base.minusMinutes(29));
         updateFeedDates(feedBlocked.getId(), base.minusMinutes(40), null);
-        updateFeedDates(feed3.getId(), base.minusMinutes(10), null);
+        updateFeedDates(feed3.getId(), base.minusMinutes(11), null);
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 05cc746 and 4af544c.

📒 Files selected for processing (1)
  • src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java (2)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
🔇 Additional comments (5)
src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java (5)

26-38: 테스트 클래스 설정이 적절합니다.

JPA 슬라이스 테스트 구성과 Testcontainers를 사용한 실제 MySQL 환경 설정이 올바르게 구성되어 있습니다. 필요한 의존성도 모두 주입되어 있습니다.


40-58: 기본 저장 및 조회 테스트가 정확합니다.

사용자와 피드를 생성하고, 영속성 컨텍스트를 초기화한 후 조회하여 모든 필드를 검증하는 로직이 올바릅니다.


60-102: 차단된 사용자 필터링 테스트가 올바릅니다.

삭제되지 않은 피드 조회 시 차단된 사용자의 피드를 제외하고, 페이지네이션과 정렬이 정확하게 동작하는지 검증합니다.


104-138: 특정 사용자의 피드 조회 테스트가 정확합니다.

이전 리뷰 코멘트에서 지적된 데이터 설정 오류가 수정되었으며, 특정 사용자의 삭제되지 않은 피드만 최신순으로 조회하는 로직이 올바르게 검증됩니다.


254-265: 헬퍼 메서드가 테스트 목적에 적합합니다.

updateFeedDates는 JPQL을 사용하여 테스트 데이터의 타임스탬프를 직접 설정하고, flushAndClear는 영속성 컨텍스트를 동기화하고 초기화합니다. 두 메서드 모두 테스트 데이터 준비에 적절한 구현입니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4af544c and d0bb557.

📒 Files selected for processing (2)
  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: The LinkedUser entity in the Leenk-BE project has a unique constraint on the combination of feed_id and user_id columns (UniqueConstraint(columnNames = {"feed_id", "user_id"})), which requires explicit flush() calls after delete operations to prevent constraint violations during the delete-and-recreate pattern used in feed updates.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: In the Leenk-BE project, the LinkedUser entity has DB unique constraints that require explicit flush() calls after deleteAllByFeed operations to prevent constraint violations when recreating the relationships immediately afterward.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java
  • src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java
🧬 Code graph analysis (1)
src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (6-15)
src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java (1)
  • LinkedUserTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
🔇 Additional comments (5)
src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java (1)

7-15: LGTM! 테스트 픽스처 구현이 적절합니다.

LinkedUser 엔티티 생성을 위한 간결하고 명확한 테스트 픽스처입니다. 빌더 패턴을 활용하여 테스트 데이터를 쉽게 생성할 수 있도록 구현되었습니다.

src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java (4)

27-39: 테스트 설정이 적절합니다.

@DataJpaTest와 TestContainers 기반의 MySQL 테스트 구성이 올바르게 설정되었습니다. 필요한 리포지토리와 EntityManager가 적절히 주입되어 있습니다.


41-65: findAllByFeed 테스트가 잘 작성되었습니다.

Given-When-Then 패턴을 따르고 있으며, flushAndClear()를 통해 영속성 컨텍스트를 관리하고 있습니다. 결과의 개수와 순서를 모두 검증하여 테스트가 충분히 포괄적입니다.


107-131: deleteAllByFeed 테스트가 올바르게 구현되었습니다.

삭제 작업 후 flushAndClear()를 호출하여 unique constraint 검증을 확실히 하고 있습니다. 이는 LinkedUser 엔티티의 (feed_id, user_id) unique constraint를 고려한 적절한 구현입니다. 또한 f1의 링크만 삭제되고 f2의 링크는 유지되는지 명확히 검증하고 있습니다.

Based on learnings, LinkedUser 엔티티는 feed_id와 user_id 컬럼 조합에 unique constraint가 있어 삭제 후 명시적인 flush가 필요합니다.


133-150: 헬퍼 메서드가 적절하게 구현되었습니다.

saveFeedWithCreateDate 메서드는 JPQL을 사용하여 자동 생성되는 타임스탬프 필드를 테스트용으로 설정하는 일반적이고 적절한 패턴입니다. flushAndClear 메서드는 영속성 컨텍스트를 관리하여 데이터베이스 제약조건 검증과 캐시 관리를 보장합니다.

Comment on lines +67 to +105
@Test
@DisplayName(("findFeedsByLinkedUser 테스트"))
void findFeedsByLinkedUser() {
// given
User me = userRepository.save(UserTestFixture.createUser(1L, "me"));
User other = userRepository.save(UserTestFixture.createUser(2L, "other"));

LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0);

Feed myFeed = saveFeedWithCreateDate(
FeedTestFixture.createFeed(null, me),
base.plusMinutes(1),
null
);
Feed f1 = saveFeedWithCreateDate(
FeedTestFixture.createFeed(null, other),
base.plusMinutes(2),
null
);
Feed deleted = saveFeedWithCreateDate(
FeedTestFixture.createFeed(null, other),
base.plusMinutes(3),
base.plusMinutes(4)
);

linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, myFeed));
linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, f1));
linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, deleted));

flushAndClear();

// when
Slice<Feed> slice = linkedUserRepository.findFeedsByLinkedUser(me, PageRequest.of(0, 10));

// then
assertThat(slice).hasSize(1);
assertThat(slice.getContent().stream().map(Feed::getId).toList())
.containsExactly(f1.getId());
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find LinkedUserRepository interface definition and findFeedsByLinkedUser method
find . -name "LinkedUserRepository.java" -type f | head -20

Repository: Leets-Makers/Leenk-BE

Length of output: 148


🏁 Script executed:

#!/bin/bash
# Read the LinkedUserRepository interface to see findFeedsByLinkedUser method
cat -n "./src/main/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepository.java"

Repository: Leets-Makers/Leenk-BE

Length of output: 1187


테스트에서 자신의 피드가 제외되는 이유를 명시적으로 문서화하세요.

findFeedsByLinkedUser 쿼리는 f.user != :user 조건으로 인해 연결된 사용자가 작성한 피드를 의도적으로 제외합니다. 테스트에서 myFeed가 결과에 포함되지 않는 것은 이 비즈니스 로직 때문입니다.

이 동작을 명확히 하기 위해 다음 중 하나를 수행하는 것을 권장합니다:

  • 테스트에 주석 추가: "자신의 피드는 제외됨" 설명
  • 명시적 assertion 추가: 자신의 피드가 결과에 없음을 검증하는 추가 검증 로직 작성

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java (1)

29-46: 테스트 구조가 잘 작성되어 있습니다!

given-when-then 패턴을 잘 따르고 있으며, BDDMockito를 사용한 모킹과 검증이 적절합니다. 테스트 픽스처를 활용하여 코드가 깔끔하고 가독성이 좋습니다.

선택적으로 테스트 메서드명과 DisplayName을 더 구체적으로 작성하면 테스트의 의도가 더 명확해질 수 있습니다. 예를 들어:

  • 메서드명: save메서드가_리액션을_정상적으로_저장하고_반환한다
  • DisplayName: "save() 메서드는 리액션을 저장하고 동일한 인스턴스를 반환한다"
🔎 선택적 개선사항: 더 명확한 테스트명
     @Test
-    @DisplayName("reactionSave 테스트")
-    void reactionSave() {
+    @DisplayName("save() 메서드는 리액션을 저장하고 동일한 인스턴스를 반환한다")
+    void save메서드가_리액션을_정상적으로_저장하고_반환한다() {
         // given
         User user = UserTestFixture.createUser(1L, "me");
         Feed feed = FeedTestFixture.createFeed(1L, user);
src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java (1)

44-58: 배치 저장 테스트가 잘 작성되었습니다.

saveAll 메서드의 위임 로직을 올바르게 검증하고 있습니다.

여러 개의 LinkedUser를 포함한 케이스를 테스트하면 배치 처리 시나리오를 더 잘 검증할 수 있습니다:

🔎 다중 항목 테스트 예시
 @Test
 @DisplayName("saveAll 테스트")
 void saveAll() {
     // given
     User user = UserTestFixture.createUser(1L, "me");
+    User user2 = UserTestFixture.createUser(2L, "you");
     Feed feed = FeedTestFixture.createFeed(1L, user);
     LinkedUser linkedUser = LinkedUserTestFixture.createLinkedUser(null, user, feed);
-    List<LinkedUser> linkedUsers = List.of(linkedUser);
+    LinkedUser linkedUser2 = LinkedUserTestFixture.createLinkedUser(null, user2, feed);
+    List<LinkedUser> linkedUsers = List.of(linkedUser, linkedUser2);
 
     // when
     linkedUserSaveService.saveAll(linkedUsers);
 
     // then
     then(linkedUserRepository).should().saveAll(linkedUsers);
 }
src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java (1)

19-21: 테스트 메서드명 개선을 고려하세요.

테스트 메서드명이 클래스명을 반복하고 있습니다. deleteComment_ShouldSetDeletedAt() 또는 deleteComment_성공() 같이 테스트하는 동작을 명확히 표현하는 이름을 사용하는 것이 좋습니다.

src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java (1)

119-165: 페이지네이션 및 탐색 로직 테스트가 철저합니다.

이전/다음 피드 탐색 로직을 hasMore 플래그와 결과 순서를 포함하여 상세하게 검증하고 있습니다. 차단된 사용자 필터링도 함께 테스트하여 실제 사용 시나리오를 잘 반영하고 있습니다.

선택사항: 추가 엣지 케이스 테스트 고려

다음과 같은 엣지 케이스에 대한 테스트를 추가로 작성하면 더욱 견고한 테스트 커버리지를 확보할 수 있습니다:

  • 요청한 개수보다 적은 피드가 반환될 때 hasMorefalse인지 확인
  • 빈 결과가 반환되는 경우
  • 모든 사용자가 차단된 경우

현재 코드는 정상 동작하며, 이는 선택적인 개선 사항입니다.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0bb557 and e933b2a.

📒 Files selected for processing (13)
  • src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java
  • src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: The LinkedUser entity in the Leenk-BE project has a unique constraint on the combination of feed_id and user_id columns (UniqueConstraint(columnNames = {"feed_id", "user_id"})), which requires explicit flush() calls after delete operations to prevent constraint violations during the delete-and-recreate pattern used in feed updates.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java
📚 Learning: 2025-08-12T14:17:56.674Z
Learnt from: hyxklee
Repo: Leets-Makers/Leenk-BE PR: 54
File: src/main/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteService.java:18-18
Timestamp: 2025-08-12T14:17:56.674Z
Learning: In the Leenk-BE project, the LinkedUser entity has DB unique constraints that require explicit flush() calls after deleteAllByFeed operations to prevent constraint violations when recreating the relationships immediately afterward.

Applied to files:

  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java
  • src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java
🧬 Code graph analysis (12)
src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java (2)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java (1)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java (1)
  • LinkedUserTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java (4)
src/main/java/leets/leenk/domain/feed/application/exception/CommentNotFoundException.java (1)
  • CommentNotFoundException (5-9)
src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java (1)
  • CommentTestFixture (7-16)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java (2)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java (1)
  • LinkedUserTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java (3)
src/main/java/leets/leenk/domain/feed/application/exception/FeedNotFoundException.java (1)
  • FeedNotFoundException (5-9)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java (1)
  • CommentTestFixture (7-16)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java (2)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
🔇 Additional comments (18)
src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java (2)

1-20: LGTM!

임포트 구성이 깔끔하고, 필요한 테스트 라이브러리들이 적절히 사용되고 있습니다.


21-28: LGTM!

Mockito 설정이 올바르게 구성되어 있으며, Mock과 InjectMocks를 통한 의존성 주입이 적절합니다.

src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java (1)

29-42: 단위 테스트가 잘 작성되었습니다.

서비스가 리포지토리에 올바르게 위임하는지 검증하는 깔끔한 테스트입니다. given-when-then 패턴과 fixture 사용이 적절합니다.

src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java (1)

14-36: 테스트 구조가 적절합니다.

소프트 삭제 로직을 검증하는 단순한 단위 테스트로, deletedAt 필드가 올바르게 설정되는지 타임스탬프 범위로 검증하고 있습니다. 테스트 픽스처를 활용하여 명확하게 작성되었습니다.

src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java (1)

28-37: 테스트 로직이 올바릅니다.

댓글 소프트 삭제 기능이 정상적으로 검증되고 있으며, 타임스탬프 범위 검증도 적절합니다.

src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java (3)

34-51: 잘 작성된 단위 테스트입니다.

Mockito를 활용하여 리포지토리 의존성을 적절히 모킹하고, BDD 스타일로 명확하게 구조화되어 있습니다. isSameAs 를 사용하여 정확한 객체 반환을 검증하고, 리포지토리 호출도 확인하고 있습니다.


53-64: 예외 처리 테스트가 적절합니다.

댓글을 찾지 못했을 때 CommentNotFoundException이 발생하는지 검증하고 있으며, 리포지토리 호출도 확인하고 있습니다. 네거티브 케이스 커버리지가 우수합니다.


66-84: 컬렉션 조회 테스트가 정확합니다.

피드별 댓글 목록 조회 기능을 검증하며, containsExactly를 사용하여 정확한 순서까지 검증하고 있습니다. 생성일 내림차순 정렬이 중요한 요구사항인 경우 적절한 검증 방법입니다.

src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java (1)

27-40: 위임 테스트가 적절합니다.

서비스가 리포지토리로의 단순 위임 역할을 하는 경우, 리포지토리 호출을 검증하는 현재 테스트가 적절합니다. 만약 saveComment 메서드가 저장된 엔티티를 반환한다면, 반환값 검증을 추가하는 것도 고려해볼 수 있습니다.

src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java (2)

35-52: 리포지토리 위임 검증이 정확합니다.

isSameAs를 사용하여 서비스가 리포지토리에서 반환된 정확한 인스턴스를 그대로 반환하는지 검증하고 있습니다. 위임 패턴 테스트에 적합한 방법입니다.


54-71: 페이징 조회 테스트가 올바릅니다.

Pageable 파라미터를 포함한 메서드 호출을 검증하고, Slice 타입 반환을 적절히 테스트하고 있습니다. 페이징 기능에 대한 단위 테스트로 적합합니다.

src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)

8-26: 잘 설계된 테스트 픽스처입니다.

두 가지 팩토리 메서드를 제공하여 일반적인 경우와 생성일시가 중요한 테스트 시나리오를 모두 지원합니다. 일관된 기본값을 사용하고 빌더 패턴으로 명확하게 구현되어 있습니다.

src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java (1)

25-37: 저장 기능 테스트가 적절합니다.

새 엔티티 생성 시나리오를 테스트하기 위해 id를 null로 설정하고, 리포지토리 호출을 검증하고 있습니다. 서비스의 위임 역할을 정확히 테스트하고 있습니다.

src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java (2)

34-49: Null 처리 테스트가 적절합니다.

업데이트 요청의 description이 null일 때 기존 값이 유지되는지 검증하고 있습니다. 중요한 엣지 케이스를 커버하고 있습니다.


51-66: 리액션 카운트 업데이트 테스트가 정확합니다.

피드, 리액션, 사용자 엔티티의 총 리액션 카운트가 올바르게 업데이트되는지 검증하고 있습니다. 복잡한 상태 변경 로직을 명확하게 테스트하고 있습니다.

src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java (2)

35-72: 테스트 구조가 잘 설계되었습니다.

Mockito를 활용한 단위 테스트 구조가 명확하고, BDD 스타일(given/when/then)을 일관되게 적용하여 가독성이 좋습니다. 정상 케이스와 예외 케이스를 모두 검증하는 것도 좋은 실천 방법입니다.


74-117: 차단된 사용자 필터링 로직과 사용자별 조회 테스트가 적절합니다.

findAll 테스트에서 차단된 사용자 목록을 올바르게 추출하여 리포지토리에 전달하는지 검증하고 있으며, findAllByUser 테스트는 특정 사용자의 피드 조회를 간결하게 테스트하고 있습니다.

src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java (1)

24-68: 리액션 조회 서비스 테스트가 명확하고 효과적입니다.

두 테스트 모두 fixture를 활용하여 깔끔하게 테스트 데이터를 생성하고, OptionalList 반환 타입에 대해 적절한 AssertJ 어설션(containsSame, isSameAs)을 사용하고 있습니다. 리포지토리 상호작용 검증도 정확합니다.

Comment on lines +25 to +38
@Test
@DisplayName("deleteAllByFeed 테스트")
void deleteAllByFeed() {
// given
User user = UserTestFixture.createUser(1L, "me");
Feed feed = FeedTestFixture.createFeed(1L, user);

// when
linkedUserDeleteService.deleteAllByFeed(feed);

// then
then(linkedUserRepository).should().deleteAllByFeed(feed);
then(linkedUserRepository).should().flush();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

호출 순서 검증이 누락되었습니다.

flush()는 unique constraint 위반을 방지하기 위해 반드시 deleteAllByFeed() 이후에 호출되어야 합니다. 현재 테스트는 두 메서드가 호출되었는지만 확인하고 순서는 검증하지 않습니다.

Based on learnings, LinkedUser 엔티티는 feed_id와 user_id 조합에 대한 unique constraint가 있어서 삭제 후 재생성 패턴에서 제약 위반을 방지하려면 명시적인 flush() 호출이 필요합니다.

🔎 순서 검증을 추가하는 제안
+import static org.mockito.Mockito.inOrder;
+
 @Test
 @DisplayName("deleteAllByFeed 테스트")
 void deleteAllByFeed() {
     // given
     User user = UserTestFixture.createUser(1L, "me");
     Feed feed = FeedTestFixture.createFeed(1L, user);
 
     // when
     linkedUserDeleteService.deleteAllByFeed(feed);
 
     // then
-    then(linkedUserRepository).should().deleteAllByFeed(feed);
-    then(linkedUserRepository).should().flush();
+    var inOrder = inOrder(linkedUserRepository);
+    inOrder.verify(linkedUserRepository).deleteAllByFeed(feed);
+    inOrder.verify(linkedUserRepository).flush();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Test
@DisplayName("deleteAllByFeed 테스트")
void deleteAllByFeed() {
// given
User user = UserTestFixture.createUser(1L, "me");
Feed feed = FeedTestFixture.createFeed(1L, user);
// when
linkedUserDeleteService.deleteAllByFeed(feed);
// then
then(linkedUserRepository).should().deleteAllByFeed(feed);
then(linkedUserRepository).should().flush();
}
import static org.mockito.Mockito.inOrder;
@Test
@DisplayName("deleteAllByFeed 테스트")
void deleteAllByFeed() {
// given
User user = UserTestFixture.createUser(1L, "me");
Feed feed = FeedTestFixture.createFeed(1L, user);
// when
linkedUserDeleteService.deleteAllByFeed(feed);
// then
var inOrder = inOrder(linkedUserRepository);
inOrder.verify(linkedUserRepository).deleteAllByFeed(feed);
inOrder.verify(linkedUserRepository).flush();
}
🤖 Prompt for AI Agents
In
src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java
around lines 25 to 38, the test only asserts that deleteAllByFeed(feed) and
flush() were called but not their order; add an InOrder verification so
deleteAllByFeed(feed) is verified before flush(), e.g., create InOrder inOrder =
inOrder(linkedUserRepository) and then call
inOrder.verify(linkedUserRepository).deleteAllByFeed(feed) followed by
inOrder.verify(linkedUserRepository).flush(); also add the necessary Mockito
import for InOrder.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java (3)

18-32: 이전 리뷰 코멘트가 반영되었습니다.

Given-When-Then 주석이 올바른 순서로 수정되었습니다. 테스트 로직도 정상적으로 설명 텍스트의 공백 처리를 검증하고 있습니다.

다만, 테스트 메서드 이름을 더 명확하게 개선하면 좋겠습니다. 예: shouldTrimAndCollapseMultipleNewlines() 또는 feedUpdate_shouldNormalizeDescriptionNewlines()

🔎 테스트 이름 개선 제안
     @Test
-    @DisplayName("feedUpdate 테스트")
-    void feedUpdate1() {
+    @DisplayName("여러 개의 연속된 줄바꿈을 하나로 정규화해야 함")
+    void shouldTrimAndCollapseMultipleNewlines() {

34-49: null 처리 케이스를 잘 검증하고 있습니다.

요청의 description이 null일 때 기존 값이 유지되는지 확인하는 중요한 테스트입니다.

마찬가지로 테스트 메서드 이름을 더 명확하게 개선하면 좋겠습니다. 예: shouldPreserveExistingDescriptionWhenRequestDescriptionIsNull()

🔎 테스트 이름 개선 제안
     @Test
-    @DisplayName("feedUpdate 테스트 - description이 null일 때 유지")
-    void feedUpdate2() {
+    @DisplayName("요청의 description이 null이면 기존 description을 유지해야 함")
+    void shouldPreserveExistingDescriptionWhenRequestDescriptionIsNull() {

51-66: 반응 수 업데이트 로직을 정확하게 검증하고 있습니다.

Feed, Reaction, User 세 엔티티의 카운트가 모두 올바르게 업데이트되는지 확인하는 포괄적인 테스트입니다.

추가로 엣지 케이스를 고려하면 테스트 커버리지를 높일 수 있습니다:

  • 음수 delta 값 (반응 취소 시나리오)
  • delta가 0인 경우
  • 매우 큰 값으로 인한 오버플로우 가능성
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e933b2a and 149fcb1.

📒 Files selected for processing (1)
  • src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java
🧰 Additional context used
🧬 Code graph analysis (1)
src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java (3)
src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java (1)
  • FeedTestFixture (8-27)
src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java (1)
  • ReactionTestFixture (7-15)
src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java (1)
  • UserTestFixture (5-14)
🔇 Additional comments (1)
src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java (1)

15-16: 테스트 클래스 구조가 깔끔합니다.

테스트 픽스처를 활용하고 Given-When-Then 패턴을 따르는 명확한 단위 테스트 구조입니다. FeedUpdateService의 직접 인스턴스화는 상태를 가지지 않는 서비스의 단위 테스트에 적합합니다.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants