1+ import { getCurrentKSTDateString , getKSTDateStringWithOffset } from '../date.util' ;
2+
3+ describe ( 'Date Utilities' , ( ) => {
4+ // 원본 Date 객체와 Date.now 함수 저장
5+ let originalDate : DateConstructor ;
6+ let originalDateNow : ( ) => number ;
7+
8+ beforeAll ( ( ) => {
9+ originalDate = global . Date ;
10+ originalDateNow = Date . now ;
11+ } ) ;
12+
13+ afterAll ( ( ) => {
14+ // 테스트 종료 후 원래 객체로 복원
15+ global . Date = originalDate ;
16+ Date . now = originalDateNow ;
17+ } ) ;
18+
19+ afterEach ( ( ) => {
20+ // 각 테스트 후 모킹 제거 및 원래 객체로 복원
21+ jest . restoreAllMocks ( ) ;
22+ global . Date = originalDate ;
23+ Date . now = originalDateNow ;
24+ } ) ;
25+
26+ /**
27+ * Date 객체를 KST 포맷 문자열로 변환하는 헬퍼 함수
28+ * @param date 변환할 Date 객체
29+ * @returns KST 포맷의 문자열 (YYYY-MM-DD HH:MM:SS+09)
30+ */
31+ const formatKST = ( date : Date ) : string => {
32+ const kst = new Date ( date . getTime ( ) + 9 * 60 * 60 * 1000 ) ;
33+ const year = kst . getUTCFullYear ( ) ;
34+ const month = String ( kst . getUTCMonth ( ) + 1 ) . padStart ( 2 , '0' ) ;
35+ const day = String ( kst . getUTCDate ( ) ) . padStart ( 2 , '0' ) ;
36+ const hour = String ( kst . getUTCHours ( ) ) . padStart ( 2 , '0' ) ;
37+ const minute = String ( kst . getUTCMinutes ( ) ) . padStart ( 2 , '0' ) ;
38+ const second = String ( kst . getUTCSeconds ( ) ) . padStart ( 2 , '0' ) ;
39+ return `${ year } -${ month } -${ day } ${ hour } :${ minute } :${ second } +09` ;
40+ } ;
41+
42+ it ( 'getCurrentKSTDateString이 KST 포맷의 문자열을 반환해야 한다' , ( ) => {
43+ // 형식 검증
44+ const result = getCurrentKSTDateString ( ) ;
45+ expect ( result ) . toMatch ( / ^ \d { 4 } - \d { 2 } - \d { 2 } \d { 2 } : \d { 2 } : \d { 2 } \+ 0 9 $ / ) ;
46+
47+ // 현재 시간 기준 내용 검증
48+ const now = new Date ( ) ;
49+ const expected = formatKST ( now ) ;
50+
51+ // 날짜 부분만 검증 (시간은 테스트 실행 중 변할 수 있음)
52+ expect ( result . slice ( 0 , 10 ) ) . toBe ( expected . slice ( 0 , 10 ) ) ;
53+ } ) ;
54+
55+ it ( 'getKSTDateStringWithOffset이 KST 포맷의 문자열을 반환해야 한다' , ( ) => {
56+ const result = getKSTDateStringWithOffset ( 30 ) ;
57+ expect ( result ) . toMatch ( / ^ \d { 4 } - \d { 2 } - \d { 2 } \d { 2 } : \d { 2 } : \d { 2 } \+ 0 9 $ / ) ;
58+ } ) ;
59+
60+ it ( 'getCurrentKSTDateString은 5분 후와 다른 값을 반환해야 한다' , ( ) => {
61+ // 고정된 시간 설정
62+ const fixedTime = new originalDate ( Date . UTC ( 2025 , 4 , 10 , 6 , 30 , 0 ) ) ; // 2025-05-10 06:30:00 UTC
63+ const fiveMinutesLater = new originalDate ( fixedTime . getTime ( ) + 5 * 60 * 1000 ) ;
64+
65+ let callCount = 0 ;
66+
67+ // Date 클래스 모킹
68+ class MockDate extends originalDate {
69+ constructor ( ...args : ConstructorParameters < typeof Date > ) {
70+ if ( args . length > 0 ) {
71+ super ( ...args ) ;
72+ } else {
73+ // new Date()로 호출될 때 다른 시간 반환
74+ super ( callCount ++ === 0 ? fixedTime . getTime ( ) : fiveMinutesLater . getTime ( ) ) ;
75+ }
76+ }
77+ }
78+
79+ global . Date = MockDate as unknown as DateConstructor ;
80+
81+ const before = getCurrentKSTDateString ( ) ;
82+ const after = getCurrentKSTDateString ( ) ;
83+
84+ expect ( before ) . not . toBe ( after ) ;
85+ } ) ;
86+
87+ it ( 'getKSTDateStringWithOffset(0)은 getCurrentKSTDateString과 동일한 값을 반환해야 한다' , ( ) => {
88+ // 시간을 고정하여 두 함수 호출 사이에 실제 시간이 변경되지 않도록 함
89+ const fixed = Date . now ( ) ;
90+ Date . now = jest . fn ( ( ) => fixed ) ;
91+
92+ const current = getCurrentKSTDateString ( ) ;
93+ const offsetZero = getKSTDateStringWithOffset ( 0 ) ;
94+
95+ expect ( current ) . toBe ( offsetZero ) ;
96+ } ) ;
97+
98+ it ( 'getKSTDateStringWithOffset(60)은 정확히 1시간 후 KST 시간을 반환해야 한다' , ( ) => {
99+ // 기준 시간과 1시간 후 시간 설정
100+ const baseTime = new Date ( ) ;
101+ const oneHourLater = new Date ( baseTime . getTime ( ) + 60 * 60 * 1000 ) ;
102+
103+ // Date 생성자 모킹
104+ let callCount = 0 ;
105+ jest . spyOn ( global , 'Date' ) . mockImplementation ( function ( this : Date , time ?: number | string | Date ) : Date {
106+ if ( time !== undefined ) return new originalDate ( time ) ;
107+ // 첫 호출과 두 번째 호출에서 다른 시간 반환
108+ return callCount ++ === 0 ? baseTime : oneHourLater ;
109+ } as unknown as ( time ?: number | string | Date ) => Date ) ;
110+
111+ const result = getKSTDateStringWithOffset ( 60 ) ;
112+ const expected = formatKST ( oneHourLater ) ;
113+
114+ expect ( result ) . toBe ( expected ) ;
115+ } ) ;
116+ } ) ;
0 commit comments