-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Post 도메인 성공 테스트 및 클래스 생성 * refactor: Post 도메인 테스트 수정 * feat: PostServiceTest 코드 작성을 위한 세팅 * fix: 테스트 중 발견한 createPost 오류 수정 * feat: createPost 테스트 구현 * feat: createdAt을 사용하지 않는 테스트 구현 * feat: TestEntityUtils를 적용해 createdAt 사용 테스트 구현 * fix: CodeRabbit 리뷰 반영, 테스트 케이스 수정 및 null 체크 보완 * fix: FakeUserService 삭제 후 테스트용SecurityContext 대체 * fix: UserServiceTest 초기화 부분 수정
- Loading branch information
1 parent
e0fb190
commit 229642f
Showing
8 changed files
with
427 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
aics-api/src/testFixtures/java/post/application/PostServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package post.application; | ||
|
||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotEquals; | ||
|
||
import kgu.developers.api.post.application.PostService; | ||
import kgu.developers.api.post.presentation.exception.PostNotFoundException; | ||
import kgu.developers.api.post.presentation.request.PostRequest; | ||
import kgu.developers.api.post.presentation.response.PostDetailResponse; | ||
import kgu.developers.api.post.presentation.response.PostPersistResponse; | ||
import kgu.developers.api.post.presentation.response.PostSummaryPageResponse; | ||
import kgu.developers.api.user.application.UserService; | ||
import kgu.developers.domain.post.domain.Category; | ||
import kgu.developers.domain.post.domain.Post; | ||
import kgu.developers.domain.user.domain.Major; | ||
import kgu.developers.domain.user.domain.User; | ||
import mock.FakePostRepository; | ||
import mock.FakeUserRepository; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.data.domain.PageRequest; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.context.SecurityContext; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
|
||
public class PostServiceTest { | ||
private PostService postService; | ||
|
||
@BeforeEach | ||
public void init() { | ||
FakePostRepository fakePostRepository = new FakePostRepository(); | ||
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); | ||
FakeUserRepository fakeUserRepository = new FakeUserRepository(); | ||
UserService userService = new UserService(bCryptPasswordEncoder, fakeUserRepository); | ||
|
||
this.postService = new PostService(fakePostRepository, userService); | ||
|
||
fakeUserRepository.save(User.builder() | ||
.id("202411345") | ||
.password(bCryptPasswordEncoder.encode("password1234")) | ||
.name("홍길동") | ||
.email("[email protected]") | ||
.phone("010-1234-5678") | ||
.major(Major.CSE) | ||
.build()); | ||
|
||
UserDetails user = userService.getUserById("202411345"); | ||
SecurityContext context = SecurityContextHolder.getContext(); | ||
context.setAuthentication( | ||
new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()) | ||
); | ||
|
||
fakePostRepository.save(Post.create( | ||
"테스트용 제목1", "테스트용 내용1", | ||
Category.DEPT_INFO, userService.getUserById("202411345") | ||
)); | ||
|
||
fakePostRepository.save(Post.create( | ||
"테스트용 제목2", "테스트용 내용2", | ||
Category.DEPT_INFO, userService.getUserById("202411345") | ||
)); | ||
} | ||
|
||
@Test | ||
@DisplayName("createPost는 게시글을 생성할 수 있다") | ||
public void createPost_Success() { | ||
// given | ||
PostRequest request = PostRequest.builder() | ||
.title("테스트용 제목3") | ||
.content("테스트용 내용3") | ||
.build(); | ||
Category category = Category.DEPT_INFO; | ||
|
||
// when | ||
PostPersistResponse response = postService.createPost(request, category); | ||
|
||
// then | ||
assertEquals(3, response.postId()); | ||
|
||
// when | ||
PostDetailResponse created = postService.getPostById(response.postId()); | ||
|
||
// then | ||
assertEquals(request.title(), created.title()); | ||
assertEquals(request.content(), created.content()); | ||
assertEquals(category.getDescription(), created.category()); | ||
} | ||
|
||
@Test | ||
@DisplayName("getPostById는 게시글을 조회할 수 있다") | ||
public void getPostById_Success() { | ||
// given | ||
Long postId = 1L; | ||
|
||
// when | ||
PostDetailResponse response = postService.getPostById(postId); | ||
|
||
// then | ||
assertEquals(postId, response.postId()); | ||
} | ||
|
||
@Test | ||
@DisplayName("getPostById는 존재하지 않는 ID로 조회시 PostNotFoundException을 발생시킨다") | ||
public void getPostById_Throws_PostNotFoundException() { | ||
// given | ||
Long postId = 10L; | ||
|
||
// when | ||
// then | ||
assertThatThrownBy( | ||
() -> postService.getPostById(postId) | ||
).isInstanceOf(PostNotFoundException.class); | ||
} | ||
|
||
@Test | ||
@DisplayName("getPostsByKeywordAndCategory는 게시글을 페이징 조회할 수 있다") | ||
public void getPostsByKeywordAndCategory_Success() { | ||
// given | ||
String keyword = "제목"; | ||
Category category = Category.DEPT_INFO; | ||
int page = 0; | ||
int size = 10; | ||
|
||
// when | ||
PostSummaryPageResponse posts = postService.getPostsByKeywordAndCategory( | ||
PageRequest.of(page, size), keyword, category | ||
); | ||
|
||
// then | ||
assertEquals(2, posts.contents().size()); | ||
} | ||
|
||
@Test | ||
@DisplayName("togglePostPinStatus는 게시글의 고정 상태를 변경할 수 있다") | ||
public void togglePostPinStatus_Success() { | ||
// given | ||
Long postId = 1L; | ||
PostDetailResponse before = postService.getPostById(postId); | ||
|
||
// when | ||
postService.togglePostPinStatus(postId); | ||
|
||
// then | ||
PostDetailResponse after = postService.getPostById(postId); | ||
assertNotEquals(before.isPinned(), after.isPinned()); | ||
} | ||
|
||
@Test | ||
@DisplayName("deletePost 이후 게시글을 조회할 수 없다") | ||
public void deletePost_Throws_PostNotFoundException() { | ||
// given | ||
Long postId = 1L; | ||
|
||
// when | ||
postService.deletePost(postId); | ||
|
||
// then | ||
assertThatThrownBy( | ||
() -> postService.getPostById(postId) | ||
).isInstanceOf(PostNotFoundException.class); | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
aics-api/src/testFixtures/java/post/presentation/PostControllerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package post.presentation; | ||
|
||
public class PostControllerTest { | ||
} |
87 changes: 87 additions & 0 deletions
87
aics-domain/src/testFixtures/java/mock/FakePostRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package mock; | ||
|
||
import kgu.developers.common.response.PageableResponse; | ||
import kgu.developers.common.response.PaginatedListResponse; | ||
import kgu.developers.domain.post.domain.Category; | ||
import kgu.developers.domain.post.domain.Post; | ||
import kgu.developers.domain.post.domain.PostRepository; | ||
import org.springframework.data.domain.Pageable; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
import java.util.stream.Collectors; | ||
|
||
public class FakePostRepository implements PostRepository { | ||
private final List<Post> data = Collections.synchronizedList(new ArrayList<>()); | ||
private final AtomicLong autoGeneratedId = new AtomicLong(0); | ||
|
||
@Override | ||
public Post save(Post post) { | ||
if (post == null) { | ||
throw new IllegalArgumentException("게시글은 null일 수 없습니다."); | ||
} | ||
if (post.getTitle() == null || post.getContent() == null) { | ||
throw new IllegalArgumentException("제목과 내용은 필수 입력값입니다."); | ||
} | ||
|
||
Post newPost = Post.builder() | ||
.id(autoGeneratedId.incrementAndGet()) | ||
.title(post.getTitle()) | ||
.content(post.getContent()) | ||
.views(post.getViews()) | ||
.category(post.getCategory()) | ||
.author(post.getAuthor()) | ||
.isPinned(post.isPinned()) | ||
.comments(new ArrayList<>(post.getComments())) | ||
.file(post.getFile()) | ||
.build(); | ||
|
||
TestEntityUtils.setCreatedAt(newPost, LocalDateTime.now()); | ||
|
||
data.add(newPost); | ||
return newPost; | ||
} | ||
|
||
@Override | ||
public PaginatedListResponse<Post> findAllByTitleContainingAndCategoryOrderByCreatedAtDesc( | ||
String keyword, Category category, Pageable pageable | ||
) { | ||
List<Post> filteredPosts = data.stream() | ||
.filter( | ||
post -> post.getTitle().contains(keyword) && post.getCategory().equals(category) | ||
) | ||
.sorted(Comparator.comparing(Post::getCreatedAt).reversed()) | ||
.collect(Collectors.toList()); | ||
|
||
int start = (int) pageable.getOffset(); | ||
int end = Math.min(start + pageable.getPageSize(), filteredPosts.size()); | ||
|
||
List<Post> paginatedPosts = start > filteredPosts.size() ? | ||
Collections.emptyList() : | ||
filteredPosts.subList(start, end); | ||
|
||
List<Long> ids = paginatedPosts.stream() | ||
.map(Post::getId) | ||
.toList(); | ||
|
||
return PaginatedListResponse.of(paginatedPosts, PageableResponse.of(pageable, ids)); | ||
} | ||
|
||
@Override | ||
public Optional<Post> findById(Long postId) { | ||
return data.stream() | ||
.filter(post -> post.getId().equals(postId)) | ||
.findAny(); | ||
} | ||
|
||
@Override | ||
public void deleteAllByDeletedAtBefore(int retentionDays) { | ||
LocalDateTime threshold = LocalDateTime.now().minusDays(retentionDays); | ||
data.removeIf(post -> post.getDeletedAt() != null && post.getDeletedAt().isBefore(threshold)); | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
aics-domain/src/testFixtures/java/mock/TestEntityUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package mock; | ||
|
||
import kgu.developers.common.domain.BaseTimeEntity; | ||
|
||
import java.lang.reflect.Field; | ||
import java.time.LocalDateTime; | ||
|
||
public class TestEntityUtils { | ||
public static void setCreatedAt(BaseTimeEntity entity, LocalDateTime createdAt) { | ||
if (entity == null || createdAt == null) { | ||
throw new IllegalArgumentException("entity와 createdAt은 null이 될 수 없습니다."); | ||
} | ||
|
||
try { | ||
Field field = BaseTimeEntity.class.getDeclaredField("createdAt"); | ||
field.setAccessible(true); | ||
field.set(entity, createdAt); | ||
} catch (NoSuchFieldException | IllegalAccessException e) { | ||
throw new RuntimeException("TestEntityUtils에서 createdAt 설정 실패", e); | ||
} | ||
} | ||
} | ||
|
4 changes: 4 additions & 0 deletions
4
aics-domain/src/testFixtures/java/post/application/PostServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package post.application; | ||
|
||
public class PostServiceTest { | ||
} |
Oops, something went wrong.