@@ -4,6 +4,17 @@ import { DBError } from '@/exception';
44
55jest . mock ( 'pg' ) ;
66
7+ // pg의 QueryResult 타입을 만족하는 mock 객체를 생성하기 위한 헬퍼 함수 생성
8+ function createMockQueryResult < T extends Record < string , unknown > > ( rows : T [ ] ) : QueryResult < T > {
9+ return {
10+ rows,
11+ rowCount : rows . length ,
12+ command : '' ,
13+ oid : 0 ,
14+ fields : [ ] ,
15+ } satisfies QueryResult < T > ;
16+ }
17+
718const mockPool : {
819 query : jest . Mock < Promise < QueryResult < Record < string , unknown > > > , unknown [ ] > ;
920} = {
@@ -15,6 +26,7 @@ describe('PostRepository', () => {
1526
1627 beforeEach ( ( ) => {
1728 repo = new PostRepository ( mockPool as unknown as Pool ) ;
29+ jest . clearAllMocks ( ) ;
1830 } ) ;
1931
2032 describe ( 'findPostsByUserId' , ( ) => {
@@ -24,13 +36,7 @@ describe('PostRepository', () => {
2436 { id : 2 , post_released_at : '2025-03-02T00:00:00Z' , daily_view_count : 20 , daily_like_count : 15 } ,
2537 ] ;
2638
27- mockPool . query . mockResolvedValue ( {
28- rows : mockPosts ,
29- rowCount : mockPosts . length ,
30- command : '' ,
31- oid : 0 ,
32- fields : [ ] ,
33- } as QueryResult ) ;
39+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
3440
3541 const result = await repo . findPostsByUserId ( 1 , undefined , 'released_at' , false ) ;
3642
@@ -44,18 +50,28 @@ describe('PostRepository', () => {
4450 { id : 1 , post_released_at : '2025-03-01T00:00:00Z' , daily_view_count : 10 , daily_like_count : 5 } ,
4551 ] ;
4652
47- mockPool . query . mockResolvedValue ( {
48- rows : mockPosts ,
49- rowCount : mockPosts . length ,
50- command : '' ,
51- oid : 0 ,
52- fields : [ ] ,
53- } as QueryResult ) ;
53+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
5454
5555 const result = await repo . findPostsByUserId ( 1 , undefined , 'released_at' , false ) ;
5656 expect ( result . posts ) . toEqual ( mockPosts ) ;
5757 expect ( result . posts [ 0 ] . id ) . toBeGreaterThan ( result . posts [ 1 ] . id ) ;
5858 } ) ;
59+
60+ it ( '쿼리에 is_active = TRUE 조건이 포함되어야 한다' , async ( ) => {
61+ const mockPosts = [
62+ { id : 1 , post_released_at : '2025-03-01T00:00:00Z' , daily_view_count : 10 , daily_like_count : 5 } ,
63+ ] ;
64+
65+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
66+
67+ await repo . findPostsByUserId ( 1 ) ;
68+
69+ // 쿼리 호출 확인
70+ expect ( mockPool . query ) . toHaveBeenCalledWith (
71+ expect . stringContaining ( "p.is_active = TRUE" ) ,
72+ expect . anything ( )
73+ ) ;
74+ } ) ;
5975 } ) ;
6076
6177 describe ( 'findPostsByUserIdWithGrowthMetrics' , ( ) => {
@@ -79,13 +95,7 @@ describe('PostRepository', () => {
7995 } ,
8096 ] ;
8197
82- mockPool . query . mockResolvedValue ( {
83- rows : mockPosts ,
84- rowCount : mockPosts . length ,
85- command : '' ,
86- oid : 0 ,
87- fields : [ ] ,
88- } as QueryResult ) ;
98+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
8999
90100 const result = await repo . findPostsByUserIdWithGrowthMetrics ( 1 ) ;
91101
@@ -113,13 +123,7 @@ describe('PostRepository', () => {
113123 } ,
114124 ] ;
115125
116- mockPool . query . mockResolvedValue ( {
117- rows : mockPosts ,
118- rowCount : mockPosts . length ,
119- command : '' ,
120- oid : 0 ,
121- fields : [ ] ,
122- } as QueryResult ) ;
126+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
123127
124128 const result = await repo . findPostsByUserIdWithGrowthMetrics ( 1 , undefined , false ) ;
125129 expect ( result . posts ) . toEqual ( mockPosts ) ;
@@ -137,13 +141,7 @@ describe('PostRepository', () => {
137141 } ,
138142 ] ;
139143
140- mockPool . query . mockResolvedValue ( {
141- rows : mockPosts ,
142- rowCount : mockPosts . length ,
143- command : '' ,
144- oid : 0 ,
145- fields : [ ] ,
146- } as QueryResult ) ;
144+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
147145
148146 const result = await repo . findPostsByUserIdWithGrowthMetrics ( 1 , "10,2" , false ) ;
149147 expect ( result . posts ) . toEqual ( mockPosts ) ;
@@ -157,21 +155,43 @@ describe('PostRepository', () => {
157155 mockPool . query . mockRejectedValue ( new Error ( 'DB connection failed' ) ) ;
158156 await expect ( repo . findPostsByUserIdWithGrowthMetrics ( 1 ) ) . rejects . toThrow ( DBError ) ;
159157 } ) ;
158+
159+ it ( '쿼리에 is_active = TRUE 조건이 포함되어야 한다' , async ( ) => {
160+ const mockPosts = [
161+ { id : 1 , view_growth : 20 , like_growth : 5 } ,
162+ ] ;
163+
164+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockPosts ) ) ;
165+
166+ await repo . findPostsByUserIdWithGrowthMetrics ( 1 ) ;
167+
168+ // 쿼리 호출 확인
169+ expect ( mockPool . query ) . toHaveBeenCalledWith (
170+ expect . stringContaining ( "p.is_active = TRUE" ) ,
171+ expect . anything ( )
172+ ) ;
173+ } ) ;
160174 } ) ;
161175
162176 describe ( 'getTotalPostCounts' , ( ) => {
163177 it ( '사용자의 총 게시글 수를 반환해야 한다' , async ( ) => {
164- mockPool . query . mockResolvedValue ( {
165- rows : [ { count : '10' } ] ,
166- rowCount : 1 ,
167- command : '' ,
168- oid : 0 ,
169- fields : [ ] ,
170- } as QueryResult ) ;
178+ mockPool . query . mockResolvedValue ( createMockQueryResult ( [ { count : '10' } ] ) ) ;
171179
172180 const count = await repo . getTotalPostCounts ( 1 ) ;
173181 expect ( count ) . toBe ( 10 ) ;
174182 } ) ;
183+
184+ it ( 'is_active = TRUE인 게시물만 카운트해야 한다' , async ( ) => {
185+ mockPool . query . mockResolvedValue ( createMockQueryResult ( [ { count : '5' } ] ) ) ;
186+
187+ await repo . getTotalPostCounts ( 1 ) ;
188+
189+ // 쿼리 호출 확인
190+ expect ( mockPool . query ) . toHaveBeenCalledWith (
191+ expect . stringContaining ( "is_active = TRUE" ) ,
192+ expect . anything ( )
193+ ) ;
194+ } ) ;
175195 } ) ;
176196
177197 describe ( '에러 발생 시 처리' , ( ) => {
@@ -193,17 +213,23 @@ describe('PostRepository', () => {
193213 last_updated_date : '2025-03-08T00:00:00Z' ,
194214 } ;
195215
196- mockPool . query . mockResolvedValue ( {
197- rows : [ mockStats ] ,
198- rowCount : 1 ,
199- command : '' ,
200- oid : 0 ,
201- fields : [ ] ,
202- } as QueryResult ) ;
216+ mockPool . query . mockResolvedValue ( createMockQueryResult ( [ mockStats ] ) ) ;
203217
204218 const result = await repo . getYesterdayAndTodayViewLikeStats ( 1 ) ;
205219 expect ( result ) . toEqual ( mockStats ) ;
206220 } ) ;
221+
222+ it ( 'is_active = TRUE인 게시물의 통계만 반환해야 한다' , async ( ) => {
223+ mockPool . query . mockResolvedValue ( createMockQueryResult ( [ { daily_view_count : 20 , daily_like_count : 15 } ] ) ) ;
224+
225+ await repo . getYesterdayAndTodayViewLikeStats ( 1 ) ;
226+
227+ // 쿼리 호출 확인
228+ expect ( mockPool . query ) . toHaveBeenCalledWith (
229+ expect . stringContaining ( "p.is_active = TRUE" ) ,
230+ expect . anything ( )
231+ ) ;
232+ } ) ;
207233 } ) ;
208234
209235 describe ( 'findPostByPostId' , ( ) => {
@@ -212,13 +238,7 @@ describe('PostRepository', () => {
212238 { date : '2025-03-08T00:00:00Z' , daily_view_count : 50 , daily_like_count : 30 } ,
213239 ] ;
214240
215- mockPool . query . mockResolvedValue ( {
216- rows : mockStats ,
217- rowCount : mockStats . length ,
218- command : '' ,
219- oid : 0 ,
220- fields : [ ] ,
221- } as QueryResult ) ;
241+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockStats ) ) ;
222242
223243 const result = await repo . findPostByPostId ( 1 ) ;
224244 expect ( result ) . toEqual ( mockStats ) ;
@@ -231,16 +251,10 @@ describe('PostRepository', () => {
231251 { date : '2025-03-08T00:00:00Z' , daily_view_count : 50 , daily_like_count : 30 } ,
232252 ] ;
233253
234- mockPool . query . mockResolvedValue ( {
235- rows : mockStats ,
236- rowCount : mockStats . length ,
237- command : '' ,
238- oid : 0 ,
239- fields : [ ] ,
240- } as QueryResult ) ;
254+ mockPool . query . mockResolvedValue ( createMockQueryResult ( mockStats ) ) ;
241255
242256 const result = await repo . findPostByPostUUID ( 'uuid-1234' , '2025-03-01' , '2025-03-08' ) ;
243257 expect ( result ) . toEqual ( mockStats ) ;
244258 } ) ;
245259 } ) ;
246- } ) ;
260+ } ) ;
0 commit comments