Skip to content

Commit 14a756e

Browse files
authored
Merge pull request #205 from prgrms-web-devcourse-final-project/Test/202
Test: 알림 이벤트 리스너 단위 테스트 진행 (#202)
2 parents 08acaf3 + fcbf246 commit 14a756e

File tree

7 files changed

+1032
-3
lines changed

7 files changed

+1032
-3
lines changed

src/main/java/com/back/domain/notification/event/community/CommunityNotificationEventListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import org.springframework.scheduling.annotation.Async;
1212
import org.springframework.stereotype.Component;
1313

14+
@Slf4j
1415
@Component
1516
@RequiredArgsConstructor
16-
@Slf4j
1717
public class CommunityNotificationEventListener {
1818

1919
private final NotificationService notificationService;

src/main/java/com/back/domain/notification/event/study/StudyNotificationEventListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
import org.springframework.scheduling.annotation.Async;
1212
import org.springframework.stereotype.Component;
1313

14+
@Slf4j
1415
@Component
1516
@RequiredArgsConstructor
16-
@Slf4j
1717
public class StudyNotificationEventListener {
1818

1919
private final NotificationService notificationService;

src/test/java/com/back/domain/board/service/CommentServiceTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.back.domain.board.post.entity.Post;
1111
import com.back.domain.board.comment.repository.CommentRepository;
1212
import com.back.domain.board.post.repository.PostRepository;
13+
import com.back.domain.notification.service.NotificationService;
1314
import com.back.domain.user.entity.User;
1415
import com.back.domain.user.entity.UserProfile;
1516
import com.back.domain.user.entity.UserStatus;
@@ -24,6 +25,7 @@
2425
import org.springframework.data.domain.Pageable;
2526
import org.springframework.data.domain.Sort;
2627
import org.springframework.test.context.ActiveProfiles;
28+
import org.springframework.test.context.bean.override.mockito.MockitoBean;
2729
import org.springframework.transaction.annotation.Transactional;
2830

2931
import java.util.List;
@@ -47,6 +49,9 @@ class CommentServiceTest {
4749
@Autowired
4850
private PostRepository postRepository;
4951

52+
@MockitoBean
53+
private NotificationService notificationService;
54+
5055
// ====================== 댓글 생성 테스트 ======================
5156

5257
@Test
@@ -496,4 +501,4 @@ void deleteReply_success() {
496501
boolean exists = commentRepository.findById(reply.getId()).isPresent();
497502
assertThat(exists).isFalse();
498503
}
499-
}
504+
}
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
package com.back.domain.notification.event.community;
2+
3+
import com.back.domain.notification.service.NotificationService;
4+
import com.back.domain.user.entity.User;
5+
import com.back.domain.user.repository.UserRepository;
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.DisplayName;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.extension.ExtendWith;
10+
import org.mockito.InjectMocks;
11+
import org.mockito.Mock;
12+
import org.mockito.junit.jupiter.MockitoExtension;
13+
14+
import java.util.Optional;
15+
16+
import static org.assertj.core.api.Assertions.*;
17+
import static org.mockito.ArgumentMatchers.*;
18+
import static org.mockito.BDDMockito.*;
19+
20+
@ExtendWith(MockitoExtension.class)
21+
@DisplayName("CommunityNotificationEventListener 테스트")
22+
class CommunityNotificationEventListenerTest {
23+
24+
@Mock
25+
private NotificationService notificationService;
26+
27+
@Mock
28+
private UserRepository userRepository;
29+
30+
@InjectMocks
31+
private CommunityNotificationEventListener listener;
32+
33+
private User actor;
34+
private User receiver;
35+
36+
@BeforeEach
37+
void setUp() {
38+
actor = User.builder()
39+
.id(1L)
40+
.username("actor")
41+
42+
.build();
43+
44+
receiver = User.builder()
45+
.id(2L)
46+
.username("receiver")
47+
48+
.build();
49+
}
50+
51+
// ====================== 댓글 작성 이벤트 ======================
52+
53+
@Test
54+
@DisplayName("댓글 작성 이벤트 수신 - 알림 생성 성공")
55+
void t1() {
56+
// given
57+
CommentCreatedEvent event = new CommentCreatedEvent(
58+
1L, // actorId (댓글 작성자)
59+
2L, // receiverId (게시글 작성자)
60+
100L, // postId
61+
200L, // commentId
62+
"댓글 내용"
63+
);
64+
65+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
66+
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));
67+
68+
// when
69+
listener.handleCommentCreated(event);
70+
71+
// then
72+
verify(notificationService).createCommunityNotification(
73+
eq(receiver),
74+
eq(actor),
75+
anyString(), // title
76+
anyString(), // content
77+
eq("/posts/100")
78+
);
79+
}
80+
81+
@Test
82+
@DisplayName("댓글 작성 이벤트 - 작성자(actor) 없음")
83+
void t2() {
84+
// given
85+
CommentCreatedEvent event = new CommentCreatedEvent(
86+
999L, // 존재하지 않는 actorId
87+
2L,
88+
100L,
89+
200L,
90+
"댓글 내용"
91+
);
92+
93+
given(userRepository.findById(999L)).willReturn(Optional.empty());
94+
95+
// when
96+
listener.handleCommentCreated(event);
97+
98+
// then
99+
verify(notificationService, never()).createCommunityNotification(
100+
any(), any(), anyString(), anyString(), anyString()
101+
);
102+
}
103+
104+
@Test
105+
@DisplayName("댓글 작성 이벤트 - 수신자(receiver) 없음")
106+
void t3() {
107+
// given
108+
CommentCreatedEvent event = new CommentCreatedEvent(
109+
1L,
110+
999L, // 존재하지 않는 receiverId
111+
100L,
112+
200L,
113+
"댓글 내용"
114+
);
115+
116+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
117+
given(userRepository.findById(999L)).willReturn(Optional.empty());
118+
119+
// when
120+
listener.handleCommentCreated(event);
121+
122+
// then
123+
verify(notificationService, never()).createCommunityNotification(
124+
any(), any(), anyString(), anyString(), anyString()
125+
);
126+
}
127+
128+
// ====================== 대댓글 작성 이벤트 ======================
129+
130+
@Test
131+
@DisplayName("대댓글 작성 이벤트 수신 - 알림 생성 성공")
132+
void t4() {
133+
// given
134+
ReplyCreatedEvent event = new ReplyCreatedEvent(
135+
1L, // actorId (대댓글 작성자)
136+
2L, // receiverId (댓글 작성자)
137+
100L, // postId
138+
200L, // parentCommentId
139+
300L, // replyId
140+
"대댓글 내용"
141+
);
142+
143+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
144+
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));
145+
146+
// when
147+
listener.handleReplyCreated(event);
148+
149+
// then
150+
verify(notificationService).createCommunityNotification(
151+
eq(receiver),
152+
eq(actor),
153+
anyString(),
154+
anyString(),
155+
eq("/posts/100#comment-200")
156+
);
157+
}
158+
159+
@Test
160+
@DisplayName("대댓글 작성 이벤트 - 작성자(actor) 없음")
161+
void t5() {
162+
// given
163+
ReplyCreatedEvent event = new ReplyCreatedEvent(
164+
999L, // 존재하지 않는 actorId
165+
2L,
166+
100L,
167+
200L,
168+
300L,
169+
"대댓글 내용"
170+
);
171+
172+
given(userRepository.findById(999L)).willReturn(Optional.empty());
173+
174+
// when
175+
listener.handleReplyCreated(event);
176+
177+
// then
178+
verify(notificationService, never()).createCommunityNotification(
179+
any(), any(), anyString(), anyString(), anyString()
180+
);
181+
}
182+
183+
// ====================== 게시글 좋아요 이벤트 ======================
184+
185+
@Test
186+
@DisplayName("게시글 좋아요 이벤트 수신 - 알림 생성 성공")
187+
void t6() {
188+
// given
189+
PostLikedEvent event = new PostLikedEvent(
190+
1L, // actorId (좋아요 누른 사람)
191+
2L, // receiverId (게시글 작성자)
192+
100L, // postId
193+
"게시글 제목"
194+
);
195+
196+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
197+
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));
198+
199+
// when
200+
listener.handlePostLiked(event);
201+
202+
// then
203+
verify(notificationService).createCommunityNotification(
204+
eq(receiver),
205+
eq(actor),
206+
anyString(),
207+
anyString(),
208+
eq("/posts/100")
209+
);
210+
}
211+
212+
@Test
213+
@DisplayName("게시글 좋아요 이벤트 - 수신자 없음")
214+
void t7() {
215+
// given
216+
PostLikedEvent event = new PostLikedEvent(
217+
1L,
218+
999L, // 존재하지 않는 receiverId
219+
100L,
220+
"게시글 제목"
221+
);
222+
223+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
224+
given(userRepository.findById(999L)).willReturn(Optional.empty());
225+
226+
// when
227+
listener.handlePostLiked(event);
228+
229+
// then
230+
verify(notificationService, never()).createCommunityNotification(
231+
any(), any(), anyString(), anyString(), anyString()
232+
);
233+
}
234+
235+
// ====================== 댓글 좋아요 이벤트 ======================
236+
237+
@Test
238+
@DisplayName("댓글 좋아요 이벤트 수신 - 알림 생성 성공")
239+
void t8() {
240+
// given
241+
CommentLikedEvent event = new CommentLikedEvent(
242+
1L, // actorId
243+
2L, // receiverId
244+
100L, // postId
245+
200L, // commentId,
246+
"댓글 내용"
247+
);
248+
249+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
250+
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));
251+
252+
// when
253+
listener.handleCommentLiked(event);
254+
255+
// then
256+
verify(notificationService).createCommunityNotification(
257+
eq(receiver),
258+
eq(actor),
259+
anyString(),
260+
anyString(),
261+
eq("/posts/100#comment-200")
262+
);
263+
}
264+
265+
@Test
266+
@DisplayName("댓글 좋아요 이벤트 - 작성자와 수신자가 같은 경우")
267+
void t9() {
268+
// given
269+
CommentLikedEvent event = new CommentLikedEvent(
270+
1L, // actorId
271+
1L, // receiverId (같은 사람)
272+
100L,
273+
200L,
274+
"댓글 내용"
275+
);
276+
277+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
278+
279+
// when
280+
listener.handleCommentLiked(event);
281+
282+
// then
283+
// NotificationService에서 자기 자신 알림 필터링 처리
284+
verify(notificationService).createCommunityNotification(
285+
eq(actor), // receiver
286+
eq(actor), // actor
287+
anyString(),
288+
anyString(),
289+
anyString()
290+
);
291+
}
292+
293+
// ====================== 예외 처리 테스트 ======================
294+
295+
@Test
296+
@DisplayName("알림 생성 중 예외 발생 - 로그만 출력하고 예외 전파 안함")
297+
void t10() {
298+
// given
299+
CommentCreatedEvent event = new CommentCreatedEvent(
300+
1L, 2L, 100L, 200L, "댓글 내용"
301+
);
302+
303+
given(userRepository.findById(1L)).willReturn(Optional.of(actor));
304+
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));
305+
306+
willThrow(new RuntimeException("알림 생성 실패"))
307+
.given(notificationService).createCommunityNotification(
308+
any(), any(), anyString(), anyString(), anyString()
309+
);
310+
311+
// when & then - 예외가 전파되지 않아야 함
312+
assertThatCode(() -> listener.handleCommentCreated(event))
313+
.doesNotThrowAnyException();
314+
315+
verify(notificationService).createCommunityNotification(
316+
any(), any(), anyString(), anyString(), anyString()
317+
);
318+
}
319+
}

0 commit comments

Comments
 (0)