22
33import static org .assertj .core .api .Assertions .assertThatThrownBy ;
44import static org .assertj .core .api .SoftAssertions .assertSoftly ;
5- import static org .mockito .BDDMockito .given ;
6- import static org .mockito .Mockito .mock ;
75
8- import java .time .Clock ;
96import java .time .Instant ;
107import java .time .LocalDate ;
8+ import java .time .LocalDateTime ;
119import java .time .ZoneId ;
1210import java .util .List ;
13- import java .util .Optional ;
11+ import java .util .stream .LongStream ;
12+ import me .bombom .api .v1 .TestFixture ;
13+ import me .bombom .api .v1 .article .domain .ArticleReadHistory ;
1414import me .bombom .api .v1 .article .repository .ArticleReadHistoryRepository ;
1515import me .bombom .api .v1 .common .exception .CIllegalArgumentException ;
1616import me .bombom .api .v1 .common .exception .ErrorDetail ;
1717import me .bombom .api .v1 .member .domain .Member ;
1818import me .bombom .api .v1 .member .dto .response .RankSummaryResponse ;
19+ import me .bombom .api .v1 .member .repository .MemberRepository ;
1920import me .bombom .api .v1 .reading .domain .ContinueReadingRankHistory ;
2021import me .bombom .api .v1 .reading .domain .ContinueReadingRealtime ;
2122import me .bombom .api .v1 .reading .domain .MonthlyReadingRankHistory ;
2223import me .bombom .api .v1 .reading .repository .ContinueReadingRankHistoryRepository ;
2324import me .bombom .api .v1 .reading .repository .ContinueReadingRealtimeRepository ;
2425import me .bombom .api .v1 .reading .repository .MonthlyReadingRankHistoryRepository ;
26+ import me .bombom .support .integration .IntegrationTest ;
27+ import me .bombom .support .time .MutableClock ;
2528import org .junit .jupiter .api .BeforeEach ;
2629import org .junit .jupiter .api .Test ;
27- import org .junit .jupiter .api .extension .ExtendWith ;
28- import org .mockito .Mock ;
29- import org .mockito .junit .jupiter .MockitoExtension ;
30- import org .springframework .data .domain .PageRequest ;
30+ import org .springframework .beans .factory .annotation .Autowired ;
3131
32- @ ExtendWith ( MockitoExtension . class )
32+ @ IntegrationTest
3333class MyPageServiceTest {
3434
35- private static final Long MEMBER_ID = 1L ;
35+ private static final ZoneId SEOUL_ZONE = ZoneId . of ( "Asia/Seoul" ) ;
3636
37- @ Mock
37+ @ Autowired
38+ private MyPageService myPageService ;
39+
40+ @ Autowired
3841 private ContinueReadingRealtimeRepository continueReadingRealtimeRepository ;
3942
40- @ Mock
43+ @ Autowired
4144 private MonthlyReadingRankHistoryRepository monthlyReadingRankHistoryRepository ;
4245
43- @ Mock
46+ @ Autowired
4447 private ContinueReadingRankHistoryRepository continueReadingRankHistoryRepository ;
4548
46- @ Mock
49+ @ Autowired
4750 private ArticleReadHistoryRepository articleReadHistoryRepository ;
4851
49- private final Clock clock = Clock .fixed (
50- Instant .parse ("2026-06-17T00:00:00Z" ),
51- ZoneId .of ("Asia/Seoul" )
52- );
52+ @ Autowired
53+ private MemberRepository memberRepository ;
5354
54- private MyPageService myPageService ;
55+ @ Autowired
56+ private MutableClock clock ;
57+
58+ private Member member ;
5559
5660 @ BeforeEach
5761 void setUp () {
58- myPageService = new MyPageService (
59- continueReadingRealtimeRepository ,
60- monthlyReadingRankHistoryRepository ,
61- continueReadingRankHistoryRepository ,
62- articleReadHistoryRepository ,
63- clock
64- );
62+ articleReadHistoryRepository .deleteAllInBatch ();
63+ monthlyReadingRankHistoryRepository .deleteAllInBatch ();
64+ continueReadingRankHistoryRepository .deleteAllInBatch ();
65+ continueReadingRealtimeRepository .deleteAllInBatch ();
66+ memberRepository .deleteAllInBatch ();
67+
68+ clock .setInstant (Instant .parse ("2026-06-17T00:00:00Z" ), SEOUL_ZONE );
69+
70+ member = memberRepository .save (TestFixture .createUniqueMember ("member" , "memberProvider" ));
6571 }
6672
6773 @ Test
6874 void 읽기_순위_카드의_value는_누적_읽은_아티클_수이다 () {
6975 // given
70- Member member = mock (Member .class );
71- given (member .getId ()).willReturn (MEMBER_ID );
72- given (monthlyReadingRankHistoryRepository .findRecentBeforePeriodByMemberId (
73- MEMBER_ID ,
74- LocalDate .of (2026 , 6 , 1 ),
75- PageRequest .of (0 , 6 )
76- ))
77- .willReturn (List .of (
78- MonthlyReadingRankHistory .builder ()
79- .memberId (MEMBER_ID )
80- .period (LocalDate .of (2026 , 5 , 1 ))
81- .readCount (8 )
82- .rankOrder (4 )
83- .build ()
84- ));
85- given (articleReadHistoryRepository .countByMemberId (MEMBER_ID )).willReturn (77 );
76+ monthlyReadingRankHistoryRepository .save (MonthlyReadingRankHistory .builder ()
77+ .memberId (member .getId ())
78+ .period (LocalDate .of (2026 , 5 , 1 ))
79+ .readCount (8 )
80+ .rankOrder (4 )
81+ .build ());
82+ articleReadHistoryRepository .saveAll (createArticleReadHistories (77 ));
8683
8784 // when
8885 RankSummaryResponse response = myPageService .getRankSummary (member , "reading" );
@@ -104,32 +101,24 @@ void setUp() {
104101 @ Test
105102 void 스트릭_순위_카드를_조회한다 () {
106103 // given
107- Member member = mock (Member .class );
108- given (member .getId ()).willReturn (MEMBER_ID );
109- given (continueReadingRealtimeRepository .findByMemberId (MEMBER_ID ))
110- .willReturn (Optional .of (ContinueReadingRealtime .builder ()
111- .memberId (MEMBER_ID )
104+ continueReadingRealtimeRepository .save (ContinueReadingRealtime .builder ()
105+ .memberId (member .getId ())
106+ .dayCount (6 )
107+ .build ());
108+ continueReadingRankHistoryRepository .saveAll (List .of (
109+ ContinueReadingRankHistory .builder ()
110+ .memberId (member .getId ())
111+ .period (LocalDate .of (2026 , 5 , 1 ))
112112 .dayCount (6 )
113- .build ()));
114- given (continueReadingRankHistoryRepository .findRecentBeforePeriodByMemberId (
115- MEMBER_ID ,
116- LocalDate .of (2026 , 6 , 1 ),
117- PageRequest .of (0 , 6 )
118- ))
119- .willReturn (List .of (
120- ContinueReadingRankHistory .builder ()
121- .memberId (MEMBER_ID )
122- .period (LocalDate .of (2026 , 5 , 1 ))
123- .dayCount (6 )
124- .rankOrder (3 )
125- .build (),
126- ContinueReadingRankHistory .builder ()
127- .memberId (MEMBER_ID )
128- .period (LocalDate .of (2025 , 12 , 1 ))
129- .dayCount (2 )
130- .rankOrder (20 )
131- .build ()
132- ));
113+ .rankOrder (3 )
114+ .build (),
115+ ContinueReadingRankHistory .builder ()
116+ .memberId (member .getId ())
117+ .period (LocalDate .of (2025 , 12 , 1 ))
118+ .dayCount (2 )
119+ .rankOrder (20 )
120+ .build ()
121+ ));
133122
134123 // when
135124 RankSummaryResponse response = myPageService .getRankSummary (member , "streak" );
@@ -151,16 +140,6 @@ void setUp() {
151140
152141 @ Test
153142 void 이전달_랭킹_이력이_없으면_currentRank는_null이다 () {
154- // given
155- Member member = mock (Member .class );
156- given (member .getId ()).willReturn (MEMBER_ID );
157- given (monthlyReadingRankHistoryRepository .findRecentBeforePeriodByMemberId (
158- MEMBER_ID ,
159- LocalDate .of (2026 , 6 , 1 ),
160- PageRequest .of (0 , 6 )
161- )).willReturn (List .of ());
162- given (articleReadHistoryRepository .countByMemberId (MEMBER_ID )).willReturn (0 );
163-
164143 // when
165144 RankSummaryResponse response = myPageService .getRankSummary (member , "reading" );
166145
@@ -175,12 +154,21 @@ void setUp() {
175154
176155 @ Test
177156 void 지원하지_않는_순위_type이면_예외가_발생한다 () {
178- // given
179- Member member = mock (Member .class );
180-
181157 // when & then
182158 assertThatThrownBy (() -> myPageService .getRankSummary (member , "article" ))
183159 .isInstanceOf (CIllegalArgumentException .class )
184160 .hasFieldOrPropertyWithValue ("errorDetail" , ErrorDetail .INVALID_REQUEST_PARAMETER_VALIDATION );
185161 }
162+
163+ private List <ArticleReadHistory > createArticleReadHistories (int count ) {
164+ return LongStream .rangeClosed (1 , count )
165+ .mapToObj (articleId -> ArticleReadHistory .builder ()
166+ .memberId (member .getId ())
167+ .articleId (articleId )
168+ .newsletterId (1L )
169+ .categoryId (1L )
170+ .readAt (LocalDateTime .of (2026 , 5 , 1 , 0 , 0 ))
171+ .build ())
172+ .toList ();
173+ }
186174}
0 commit comments