-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/#123 댓글 테스트 코드 구현 #125
Conversation
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough이 풀 리퀘스트에서는 Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Outside diff range and nitpick comments (11)
aics-api/src/testFixtures/java/mock/TestContainer.java (1)
Line range hint
1-43
: 테스트 컨테이너 구조 개선 제안현재 테스트 컨테이너의 생성자가 다소 길어지고 있습니다. 가독성과 유지보수성을 위해 다음과 같은 개선을 제안드립니다:
- 빌더 패턴 적용
- 의존성 초기화 메소드 분리
다음과 같은 리팩토링을 제안합니다:
public class TestContainer { // ... existing fields ... private TestContainer(Builder builder) { this.userRepository = builder.userRepository; this.postRepository = builder.postRepository; // ... other assignments } public static Builder builder() { return new Builder(); } public static class Builder { private UserRepository userRepository; private PostRepository postRepository; // ... other fields public Builder userRepository(UserRepository userRepository) { this.userRepository = userRepository; return this; } public Builder postRepository(PostRepository postRepository) { this.postRepository = postRepository; return this; } public TestContainer build() { if (userRepository == null) { userRepository = new FakeUserRepository(); } if (postRepository == null) { postRepository = new FakePostRepository(); } return new TestContainer(this); } } }aics-domain/src/testFixtures/java/mock/FakeProfessorRepository.java (1)
27-27
: 불필요한 빈 줄을 제거해주세요.코드의 가독성을 위해 불필요한 빈 줄은 제거하는 것이 좋습니다.
data.add(newProfessor); - return newProfessor;
aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java (2)
16-32
: 테스트 케이스 보완 필요현재 테스트는 기본적인 생성 로직만 검증하고 있습니다. 다음과 같은 추가 검증이 필요합니다:
- 유효하지 않은 입력값에 대한 테스트
- null 값 처리에 대한 테스트
- 최대 길이 제한 검증
다음과 같은 테스트 케이스 추가를 제안합니다:
@Test @DisplayName("댓글 내용이 null이면 예외가 발생한다") public void createComment_WithNullContent_ThrowsException() { // given String content = null; User author = getUser(); Post post = getPost(); // when & then assertThrows(IllegalArgumentException.class, () -> Comment.create(content, author, post)); }
51-59
: 테스트 데이터 개선 필요테스트 데이터 생성 메서드에서 하드코딩된 값들이 테스트의 의도를 명확히 전달하지 못합니다.
TestFixture 또는 Builder 패턴을 사용하여 테스트 데이터 생성 로직을 개선하는 것을 추천합니다.
aics-api/src/main/java/kgu/developers/api/comment/presentation/CommentController.java (1)
5-14
: 중복된 import 문 정리 필요Spring 관련 import 문들이 개별적으로 선언되어 있어 코드가 길어지고 가독성이 떨어집니다.
다음과 같이 정리하는 것을 추천합니다:
-import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*;aics-api/src/testFixtures/java/comment/application/CommentServiceTest.java (3)
42-49
: 테스트 데이터의 상수화가 필요합니다.테스트 데이터에 하드코딩된 값들이 여러 곳에서 사용될 수 있습니다. 이를 상수로 추출하여 재사용성과 유지보수성을 높이는 것이 좋습니다.
다음과 같이 개선해보세요:
+ private static final String TEST_USER_ID = "202411345"; + private static final String TEST_USER_PASSWORD = "password1234"; + private static final String TEST_USER_NAME = "홍길동"; + private static final String TEST_USER_EMAIL = "[email protected]"; + private static final String TEST_USER_PHONE = "010-1234-5678"; testContainer.userRepository.save(User.builder() - .id("202411345") - .password("password1234") - .name("홍길동") - .email("[email protected]") - .phone("010-1234-5678") + .id(TEST_USER_ID) + .password(TEST_USER_PASSWORD) + .name(TEST_USER_NAME) + .email(TEST_USER_EMAIL) + .phone(TEST_USER_PHONE) .major(Major.CSE) .build());
79-83
: 보안 컨텍스트 설정을 별도 메서드로 분리하세요.보안 컨텍스트 설정 로직을 재사용 가능한 헬퍼 메서드로 추출하면 코드의 가독성과 유지보수성이 향상됩니다.
다음과 같이 개선해보세요:
+ private void setSecurityContext(UserDetails user) { + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication( + new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()) + ); + } UserDetails user = testContainer.userService.getUserById("202411345"); - SecurityContext context = SecurityContextHolder.getContext(); - context.setAuthentication( - new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()) - ); + setSecurityContext(user);
103-117
: getComments 테스트의 검증을 강화해주세요.현재 테스트는 댓글의 내용만 검증하고 있습니다. 댓글의 다른 중요한 속성들도 함께 검증하면 좋겠습니다.
다음과 같이 검증을 보완해보세요:
// then assertEquals(comments.size(), 2); - assertEquals(comments.get(0).content(), "get"); - assertEquals(comments.get(1).content(), "test!"); + CommentResponse firstComment = comments.get(0); + assertEquals(firstComment.content(), "get"); + assertEquals(firstComment.authorId(), TEST_USER_ID); + assertFalse(firstComment.isDeleted()); + + CommentResponse secondComment = comments.get(1); + assertEquals(secondComment.content(), "test!"); + assertEquals(secondComment.authorId(), TEST_USER_ID); + assertFalse(secondComment.isDeleted());aics-domain/src/testFixtures/java/mock/FakeCommentRepository.java (3)
13-15
: 스레드 안전성에 대한 설명 추가 필요
Collections.synchronizedList
와AtomicLong
을 사용하여 스레드 안전성을 보장하고 있습니다. 이러한 중요한 구현 세부사항을 문서화하면 좋을 것 같습니다.다음과 같이 클래스 레벨 문서를 추가하는 것을 제안합니다:
+/** + * CommentRepository의 테스트용 구현체입니다. + * 멀티스레드 환경에서의 테스트를 위해 스레드 안전한 컬렉션과 ID 생성기를 사용합니다. + */ public class FakeCommentRepository implements CommentRepository {
33-38
: 대용량 데이터셋에 대한 성능 최적화 고려현재 구현은 정확하지만, 데이터가 많아질 경우 성능 이슈가 발생할 수 있습니다. 실제 환경을 더 잘 시뮬레이션하기 위해 인덱스 구조를 고려해볼 수 있습니다.
Map<Long, List<Comment>>
를 사용하여 postId별로 댓글을 그룹화하는 것을 고려해보세요. 이는 실제 데이터베이스의 인덱스 동작을 더 잘 반영할 것입니다.
48-53
: 삭제 로직 관련 인덱스 업데이트 필요
removeIf
를 사용한 구현은 스레드 안전하지만, 앞서 제안된 인덱스 구조를 도입할 경우 해당 인덱스들도 함께 업데이트해야 합니다.삭제된 데이터에 대해 인덱스도 함께 정리하는 것이 좋습니다. 실제 데이터베이스의 동작을 더 정확하게 시뮬레이션할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (11)
aics-api/src/main/java/kgu/developers/api/comment/application/CommentService.java
(3 hunks)aics-api/src/main/java/kgu/developers/api/comment/presentation/CommentController.java
(3 hunks)aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentRequest.java
(1 hunks)aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentUpdateRequest.java
(1 hunks)aics-api/src/testFixtures/java/comment/application/CommentServiceTest.java
(1 hunks)aics-api/src/testFixtures/java/comment/presentation/CommentControllerTest.java
(1 hunks)aics-api/src/testFixtures/java/mock/TestContainer.java
(2 hunks)aics-domain/src/testFixtures/java/comment/application/CommentServiceTest.java
(1 hunks)aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java
(1 hunks)aics-domain/src/testFixtures/java/mock/FakeCommentRepository.java
(1 hunks)aics-domain/src/testFixtures/java/mock/FakeProfessorRepository.java
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- aics-api/src/testFixtures/java/comment/presentation/CommentControllerTest.java
- aics-domain/src/testFixtures/java/comment/application/CommentServiceTest.java
🔇 Additional comments (8)
aics-api/src/testFixtures/java/mock/TestContainer.java (3)
7-7
: import 문이 적절하게 추가되었습니다.
Post 관련 기능 테스트를 위한 필수 import 문들이 잘 추가되었습니다.
Also applies to: 11-11
19-20
: Post 관련 필드가 적절하게 선언되었습니다.
테스트에 필요한 PostService
와 PostRepository
가 final로 선언되어 불변성이 보장되었습니다.
41-42
: 의존성 주입 순서 검증이 필요합니다.
PostService
생성자에 주입되는 의존성들의 순서가 올바른지 확인이 필요합니다.
다음 스크립트로 PostService
생성자의 파라미터 순서를 확인하겠습니다:
✅ Verification successful
의존성 주입 순서가 올바르게 되어있습니다.
PostService
클래스는 @RequiredArgsConstructor
를 사용하여 생성자를 자동으로 생성하며, 필드 선언 순서와 동일한 순서로 의존성이 주입됩니다:
private final PostRepository postRepository;
private final UserService userService;
테스트 코드에서 사용된 new PostService(postRepository, userService)
의 파라미터 순서가 필드 선언 순서와 일치하므로 올바르게 구현되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# PostService 생성자의 파라미터 순서 확인
ast-grep --pattern 'class PostService {
$$$
PostService($$$) {
$$$
}
$$$
}'
Length of output: 89
Script:
#!/bin/bash
# PostService 클래스 파일 찾기
fd "PostService.java"
Length of output: 97
Script:
#!/bin/bash
# PostService 클래스의 내용 확인
rg "class PostService" -A 10
Length of output: 2636
Script:
#!/bin/bash
# PostService 생성자 패턴 검색
rg "PostService\([^)]*\)" -A 2
Length of output: 592
Script:
#!/bin/bash
# PostService 생성자 정의 확인
rg "public PostService\([^)]*\)" -A 3 aics-api/src/main/java/kgu/developers/api/post/application/PostService.java
Length of output: 115
Script:
#!/bin/bash
# PostService.java 파일의 전체 내용 확인
cat aics-api/src/main/java/kgu/developers/api/post/application/PostService.java
Length of output: 3411
aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentUpdateRequest.java (1)
9-14
: 코드 구조가 깔끔하고 적절합니다!
레코드 클래스의 구현이 잘 되어있으며, 다음과 같은 장점들이 있습니다:
@NotBlank
검증을 통한 데이터 유효성 검사- Swagger 문서화를 통한 명확한 API 스펙 정의
- Builder 패턴 적용으로 인한 객체 생성의 유연성
aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentRequest.java (1)
9-11
: 요청 클래스들 간의 관계 검증이 필요합니다.
CommentRequest
와 CommentUpdateRequest
클래스가 공존하는 상황에서:
- 각 클래스의 사용 목적과 범위가 명확한지 확인이 필요합니다
- 유사한 필드들의 중복 여부를 검토해야 합니다
✅ Verification successful
Let's examine the actual implementations to understand the relationship better.
Let's check the service layer to understand how these requests are handled.
요청 클래스들의 역할이 명확하게 구분되어 있습니다.
각 클래스의 용도와 구조가 명확히 분리되어 있음을 확인했습니다:
CommentRequest
: 새 댓글 생성 시 사용 (postId, content 필드)CommentUpdateRequest
: 기존 댓글 수정 시 사용 (content 필드만 포함)
두 클래스는 각각의 API 엔드포인트에서 적절하게 활용되고 있으며, 불필요한 중복이 없습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# CommentRequest와 CommentUpdateRequest의 사용처를 확인
echo "=== CommentRequest 사용처 확인 ==="
rg -l "CommentRequest" --type java
echo "=== CommentUpdateRequest 사용처 확인 ==="
rg -l "CommentUpdateRequest" --type java
Length of output: 899
Script:
#!/bin/bash
# Check implementations of both request classes and their usage in controller
echo "=== CommentRequest Implementation ==="
rg -A 10 "class CommentRequest" --type java
echo "=== CommentUpdateRequest Implementation ==="
rg -A 10 "class CommentUpdateRequest" --type java
echo "=== Controller Usage ==="
rg -A 5 "CommentRequest|CommentUpdateRequest" aics-api/src/main/java/kgu/developers/api/comment/presentation/CommentController.java
Length of output: 1181
Script:
#!/bin/bash
# Check service layer implementation
echo "=== CommentService Implementation ==="
rg -A 10 "createComment|updateComment" aics-api/src/main/java/kgu/developers/api/comment/application/CommentService.java
echo "=== Request Classes Content ==="
cat aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentRequest.java
echo "---"
cat aics-api/src/main/java/kgu/developers/api/comment/presentation/request/CommentUpdateRequest.java
Length of output: 2406
aics-domain/src/testFixtures/java/mock/FakeProfessorRepository.java (1)
Line range hint 16-26
: 테스트 데이터 생성 로직이 잘 구현되어 있습니다!
다음과 같은 장점들이 있습니다:
AtomicLong
을 통한 안전한 ID 생성- Builder 패턴을 활용한 명확한 객체 생성
- 스레드 안전성 보장
aics-api/src/main/java/kgu/developers/api/comment/application/CommentService.java (1)
Line range hint 63-67
: 메서드 가시성 변경에 대한 검토 필요
getById
메서드의 가시성이 private에서 public으로 변경되었습니다. 이는 캡슐화를 약화시킬 수 있습니다.
다음 스크립트로 메서드 사용처를 확인해보세요:
✅ Verification successful
Let me check if there are any other usages of this method in the codebase, particularly in non-test files.
getById
메서드의 가시성 변경은 적절합니다
getById
메서드는 내부적으로 updateComment
와 deleteComment
메서드에서 사용되고 있으며, 테스트 코드에서도 검증 목적으로 활용되고 있습니다. 이는 PostService
와 유사한 패턴으로, 도메인 객체의 조회 및 검증을 위한 일관된 접근 방식을 제공합니다. 따라서 public 가시성은 적절한 설계 선택입니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# getById 메서드의 외부 사용 여부 확인
rg "commentService\.getById" -t java
Length of output: 732
Script:
#!/bin/bash
# Check for any internal usage of getById within CommentService
ast-grep --pattern 'getById($$$)' aics-api/src/main/java/kgu/developers/api/comment/application/CommentService.java
# Check for any other classes that might be using this method
rg "getById\(" -t java --glob "!*Test.java" -A 2
Length of output: 4753
aics-domain/src/testFixtures/java/mock/FakeCommentRepository.java (1)
18-30
: Comment 엔티티 생성 시 누락된 필드 확인 필요
현재 구현에서는 기본적인 필드만 복사하고 있습니다. deletedAt
이나 다른 필드들이 있다면 함께 복사되어야 합니다.
다음 스크립트로 Comment 엔티티의 모든 필드를 확인해보겠습니다:
✅ Verification successful
Let's try to find the Comment entity using different commands.
Let's check if Comment extends BaseTimeEntity and what fields it contains.
Comment 엔티티의 모든 필드가 올바르게 복사되고 있음을 확인했습니다
FakeCommentRepository의 save 메서드는 Comment 엔티티의 모든 필수 필드를 정확하게 복사하고 있습니다:
- id (자동 생성)
- content
- author
- post
- createdAt (BaseTimeEntity에서 상속, TestEntityUtils로 설정)
BaseTimeEntity의 updatedAt은 테스트 환경에서는 중요하지 않으며, 추가적인 필드(deletedAt 등)는 존재하지 않습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
ast-grep --pattern 'class Comment {
$$$
}'
Length of output: 46
Script:
#!/bin/bash
# Search for Comment class definition using ripgrep
rg "class Comment" -A 10
# Also search for any fields or properties in files containing Comment
rg "class Comment" --files-with-matches | xargs rg "private|protected"
Length of output: 10087
Script:
#!/bin/bash
# Check BaseTimeEntity fields
rg "class BaseTimeEntity" -A 10
# Check if there are any additional fields in Comment class
rg "class Comment.*extends BaseTimeEntity" -A 20
Length of output: 3251
aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java
Outdated
Show resolved
Hide resolved
aics-api/src/main/java/kgu/developers/api/comment/application/CommentService.java
Show resolved
Hide resolved
aics-api/src/main/java/kgu/developers/api/comment/presentation/CommentController.java
Outdated
Show resolved
Hide resolved
aics-api/src/testFixtures/java/comment/application/CommentServiceTest.java
Show resolved
Hide resolved
aics-api/src/testFixtures/java/comment/application/CommentServiceTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
깔끔한 테스트 코드 감사합니다! 한가지 코멘트만 확인부탁드려요~
aics-domain/src/testFixtures/java/comment/domain/CommentDomainTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM👍
Summary
댓글 테스트 코드 구현
Tasks