Skip to content

Commit 04a4352

Browse files
authored
Merge pull request #175 from SWU-Elixir/test/173-challenge
test: ChallengeAchievementService 테스트 코드 작성
2 parents 599a292 + 4db5216 commit 04a4352

1 file changed

Lines changed: 298 additions & 0 deletions

File tree

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
package BE_Elixir.Elixir.domain.challenge.service;
2+
3+
import BE_Elixir.Elixir.domain.challenge.dto.response.ChallengeCompletedResponseDTO;
4+
import BE_Elixir.Elixir.domain.challenge.dto.response.ChallengeProgressResponseDTO;
5+
import BE_Elixir.Elixir.domain.challenge.entity.Challenge;
6+
import BE_Elixir.Elixir.domain.challenge.entity.ChallengeAchievement;
7+
import BE_Elixir.Elixir.domain.challenge.entity.ChallengeAchievementId;
8+
import BE_Elixir.Elixir.domain.challenge.repository.ChallengeAchievementRepository;
9+
import BE_Elixir.Elixir.domain.challenge.repository.ChallengeRepository;
10+
import BE_Elixir.Elixir.domain.member.entity.Member;
11+
import BE_Elixir.Elixir.domain.member.repository.MemberRepository;
12+
import BE_Elixir.Elixir.global.exception.CustomException;
13+
import BE_Elixir.Elixir.global.exception.ErrorCode;
14+
import org.junit.jupiter.api.*;
15+
import org.junit.jupiter.api.extension.ExtendWith;
16+
import org.mockito.InjectMocks;
17+
import org.mockito.Mock;
18+
import org.mockito.junit.jupiter.MockitoExtension;
19+
20+
import java.time.LocalDate;
21+
import java.time.LocalDateTime;
22+
import java.util.Optional;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.junit.jupiter.api.Assertions.assertThrows;
26+
import static org.mockito.ArgumentMatchers.*;
27+
import static org.mockito.Mockito.*;
28+
29+
30+
@ExtendWith(MockitoExtension.class)
31+
@DisplayName("ChallengeAchievementService 테스트")
32+
class ChallengeAchievementServiceTest {
33+
@InjectMocks
34+
private ChallengeAchievementService service;
35+
36+
@Mock private ChallengeRepository challengeRepository;
37+
@Mock private ChallengeAchievementRepository challengeAchievementRepository;
38+
@Mock private MemberRepository memberRepository;
39+
40+
private Challenge challenge;
41+
private ChallengeAchievement achievement;
42+
private Member member;
43+
private Long challengeId;
44+
45+
@BeforeEach
46+
void setUp() {
47+
member = Member.builder()
48+
.id(1L)
49+
.email("test@example.com")
50+
.nickname("testUser")
51+
.build();
52+
53+
challengeId = 100L;
54+
55+
challenge = new Challenge();
56+
challenge.setId(challengeId);
57+
challenge.setName("건강왕");
58+
challenge.setYear(2025);
59+
challenge.setMonth(8);
60+
challenge.setAchievementName("건강왕");
61+
challenge.setAchievementImageUrl("achievement.png");
62+
63+
achievement = new ChallengeAchievement();
64+
achievement.setMemberId(member.getId());
65+
achievement.setChallengeId(challengeId);
66+
67+
// 모든 목표 달성
68+
achievement.setStep1Goal1Achieved(true);
69+
achievement.setStep1Goal2Achieved(true);
70+
achievement.setStep2Goal1Achieved(true);
71+
achievement.setStep2Goal2Achieved(true);
72+
achievement.setStep3Goal1Achieved(true);
73+
achievement.setStep3Goal2Achieved(true);
74+
achievement.setStep4Goal1Achieved(true);
75+
achievement.setStep4Goal2Achieved(true);
76+
}
77+
78+
@Nested
79+
@DisplayName("save 메서드")
80+
class SaveTests {
81+
@Test
82+
@DisplayName("성공: 챌린지 달성 정보 저장")
83+
void save_success() {
84+
// given
85+
when(challengeAchievementRepository.save(any())).thenReturn(achievement);
86+
87+
// when
88+
service.save(achievement);
89+
90+
// then
91+
verify(challengeAchievementRepository, times(1)).save(achievement);
92+
}
93+
}
94+
95+
@Nested
96+
@DisplayName("getProgress 메서드")
97+
class GetProgressTests {
98+
@Test
99+
@DisplayName("성공: 진행 상황 조회")
100+
void getProgress_success() {
101+
// given
102+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt())).thenReturn(Optional.of(challenge));
103+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
104+
.thenReturn(Optional.of(achievement));
105+
when(challengeRepository.findById(challengeId)).thenReturn(Optional.of(challenge));
106+
107+
// when
108+
ChallengeProgressResponseDTO result = service.getProgress(member.getId());
109+
110+
// then
111+
assertThat(result).isNotNull();
112+
assertThat(result.getName()).isEqualTo("건강왕");
113+
}
114+
115+
@Test
116+
@DisplayName("예외: 해당 월 챌린지가 없으면 CustomException 발생")
117+
void getProgress_fail_noChallenge() {
118+
// given
119+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt()))
120+
.thenReturn(Optional.empty());
121+
122+
// when & then
123+
assertThrows(CustomException.class, () -> service.getProgress(member.getId()));
124+
}
125+
}
126+
127+
@Nested
128+
@DisplayName("createIfNotExists 메서드")
129+
class CreateIfNotExistsTests {
130+
@Test
131+
@DisplayName("성공: 기존 데이터 반환")
132+
void createIfNotExists_existing() {
133+
// given
134+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt()))
135+
.thenReturn(Optional.of(challenge));
136+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
137+
.thenReturn(Optional.of(achievement));
138+
139+
// when
140+
ChallengeAchievement result = service.createIfNotExists(member.getId());
141+
142+
// then
143+
assertThat(result).isSameAs(achievement);
144+
}
145+
146+
@Test
147+
@DisplayName("성공: 기존 데이터 없으면 새로 생성")
148+
void createIfNotExists_new() {
149+
// given
150+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt()))
151+
.thenReturn(Optional.of(challenge));
152+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
153+
.thenReturn(Optional.empty());
154+
when(challengeAchievementRepository.save(any())).thenReturn(achievement);
155+
156+
// when
157+
ChallengeAchievement result = service.createIfNotExists(member.getId());
158+
159+
// then
160+
assertThat(result).isSameAs(achievement);
161+
verify(challengeAchievementRepository).save(any());
162+
}
163+
164+
@Test
165+
@DisplayName("예외: 해당 월 챌린지가 없으면 CustomException 발생")
166+
void createIfNotExists_fail_noChallenge() {
167+
// given
168+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt()))
169+
.thenReturn(Optional.empty());
170+
171+
// when & then
172+
assertThrows(CustomException.class, () -> service.createIfNotExists(member.getId()));
173+
}
174+
}
175+
176+
@Nested
177+
@DisplayName("getChallengeCompletion 메서드")
178+
class GetChallengeCompletionTests {
179+
@Test
180+
@DisplayName("성공: 모든 목표 달성 후 완료 상태 반환")
181+
void getChallengeCompletion_completed() {
182+
// given
183+
achievement.setStep4Goal1Achieved(true);
184+
achievement.setStep4Goal2Achieved(true);
185+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt())).thenReturn(Optional.of(challenge));
186+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
187+
.thenReturn(Optional.of(achievement));
188+
when(challengeRepository.findById(challengeId)).thenReturn(Optional.of(challenge));
189+
when(challengeAchievementRepository.save(any())).thenReturn(achievement);
190+
191+
// when
192+
ChallengeCompletedResponseDTO result = service.getChallengeCompletion(member.getId());
193+
194+
// then
195+
assertThat(result.isChallengeCompleted()).isTrue();
196+
}
197+
198+
@Test
199+
@DisplayName("예외: 해당 월 챌린지가 없으면 CustomException 발생")
200+
void getChallengeCompletion_fail_noChallenge() {
201+
// given
202+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt()))
203+
.thenReturn(Optional.empty());
204+
205+
// when & then
206+
assertThrows(CustomException.class, () -> service.getChallengeCompletion(member.getId()));
207+
}
208+
}
209+
210+
@Nested
211+
@DisplayName("getBeforeProgress 메서드")
212+
class GetBeforeProgressTests {
213+
@Test
214+
@DisplayName("성공: 이전 진행 상황 조회 (기록 있음)")
215+
void getBeforeProgress_withRecord() {
216+
// given
217+
when(challengeRepository.findById(challengeId)).thenReturn(Optional.of(challenge));
218+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
219+
.thenReturn(Optional.of(achievement));
220+
221+
// when
222+
ChallengeProgressResponseDTO result = service.getBeforeProgress(member.getId(), challengeId);
223+
224+
// then
225+
assertThat(result).isNotNull();
226+
}
227+
228+
@Test
229+
@DisplayName("성공: 이전 진행 상황 조회 (기록 없음)")
230+
void getBeforeProgress_noRecord() {
231+
// given
232+
when(challengeRepository.findById(challengeId)).thenReturn(Optional.of(challenge));
233+
when(challengeAchievementRepository.findByChallengeIdAndMemberId(challengeId, member.getId()))
234+
.thenReturn(Optional.empty());
235+
236+
// when
237+
ChallengeProgressResponseDTO result = service.getBeforeProgress(member.getId(), challengeId);
238+
239+
// then
240+
assertThat(result).isNotNull();
241+
}
242+
243+
@Test
244+
@DisplayName("예외: 해당 챌린지가 없으면 CustomException 발생")
245+
void getBeforeProgress_fail_noChallenge() {
246+
// given
247+
when(challengeRepository.findById(challengeId)).thenReturn(Optional.empty());
248+
249+
// when & then
250+
assertThrows(CustomException.class, () -> service.getBeforeProgress(member.getId(), challengeId));
251+
}
252+
}
253+
254+
@Nested
255+
@DisplayName("challengeParticipation 메서드")
256+
class ChallengeParticipationTests {
257+
@Test
258+
@DisplayName("성공: 기존 기록이 없으면 새로 저장")
259+
void challengeParticipation_new() {
260+
// given
261+
when(memberRepository.findByEmail(anyString()))
262+
.thenReturn(Optional.of(member));
263+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt())).thenReturn(Optional.of(challenge));
264+
when(challengeAchievementRepository.existsById(any(ChallengeAchievementId.class))).thenReturn(false);
265+
266+
// when
267+
service.challengeParticipation("test@test.com");
268+
269+
// then
270+
verify(challengeAchievementRepository).save(any(ChallengeAchievement.class));
271+
}
272+
273+
@Test
274+
@DisplayName("성공: 이번 달 챌린지가 없으면 저장하지 않음")
275+
void challengeParticipation_noChallengeThisMonth() {
276+
// given
277+
when(memberRepository.findByEmail(anyString()))
278+
.thenReturn(Optional.of(member));
279+
when(challengeRepository.findByYearAndMonth(anyInt(), anyInt())).thenReturn(Optional.empty());
280+
281+
// when
282+
service.challengeParticipation("test@test.com");
283+
284+
// then
285+
verify(challengeAchievementRepository, never()).save(any());
286+
}
287+
288+
@Test
289+
@DisplayName("예외: 회원이 없으면 CustomException 발생")
290+
void challengeParticipation_fail_noMember() {
291+
// given
292+
when(memberRepository.findByEmail(anyString())).thenReturn(Optional.empty());
293+
294+
// when & then
295+
assertThrows(CustomException.class, () -> service.challengeParticipation("test@test.com"));
296+
}
297+
}
298+
}

0 commit comments

Comments
 (0)