diff --git a/frontend/src/shared/hooks/useDebounceEffect.test.ts b/frontend/src/shared/hooks/useDebounceEffect.test.ts new file mode 100644 index 000000000..2f8216867 --- /dev/null +++ b/frontend/src/shared/hooks/useDebounceEffect.test.ts @@ -0,0 +1,44 @@ +import { renderHook, act } from '@testing-library/react'; +import useDebounceEffect from './useDebounceEffect'; + +jest.useFakeTimers(); + +describe('useDebounceEffect 테스트. debounce 제한 딜레이를 0.5초로 둘 경우', () => { + test('0.499초 지났을 때, 한 번도 실행되지 않는다.', () => { + const fn = jest.fn(); + const { rerender } = renderHook(({ deps, delay }) => useDebounceEffect(fn, deps, delay), { + initialProps: { deps: 'dependency1', delay: 500 }, + }); + + expect(fn).not.toBeCalled(); + + rerender({ deps: 'dependency2', delay: 500 }); + rerender({ deps: 'dependency3', delay: 500 }); + rerender({ deps: 'dependency4', delay: 500 }); + + act(() => { + jest.advanceTimersByTime(499); + }); + + expect(fn).not.toBeCalled(); + }); + + test('0.5초 지났을 때, 한 번만 실행된다.', () => { + const fn = jest.fn(); + const { rerender } = renderHook(({ deps, delay }) => useDebounceEffect(fn, deps, delay), { + initialProps: { deps: 'dependency1', delay: 500 }, + }); + + expect(fn).not.toBeCalled(); + + rerender({ deps: 'dependency2', delay: 500 }); + rerender({ deps: 'dependency3', delay: 500 }); + rerender({ deps: 'dependency4', delay: 500 }); + + act(() => { + jest.advanceTimersByTime(500); + }); + + expect(fn).toBeCalledTimes(1); + }); +}); diff --git a/frontend/src/shared/hooks/useFetch.test.ts b/frontend/src/shared/hooks/useFetch.test.ts new file mode 100644 index 000000000..6e7da8845 --- /dev/null +++ b/frontend/src/shared/hooks/useFetch.test.ts @@ -0,0 +1,38 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import useFetch from './useFetch'; + +describe('useFetch 테스트', () => { + let fetcher: jest.Mock; + + beforeEach(() => { + fetcher = jest.fn(); + }); + + test('fetch가 성공했을 경우, isLoading 은 false, data는 mockData, error은 null이다.', async () => { + const mockData = { key: 'value' }; + fetcher.mockResolvedValueOnce(mockData); + const { result } = renderHook(() => useFetch(fetcher, true)); + + expect(result.current.isLoading).toBe(true); + + waitFor(() => { + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toEqual(mockData); + expect(result.current.error).toBe(null); + }); + }); + + test('fetch가 실패했을 경우, isLoading 은 false, datas는 null, error은 mockError다.', async () => { + const mockError = { message: 'An error occurred' }; + fetcher.mockRejectedValueOnce(mockError); + const { result } = renderHook(() => useFetch(fetcher, true)); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBe(null); + expect(result.current.error).toEqual(mockError); + }); + }); +}); diff --git a/frontend/src/shared/hooks/useMutation.test.ts b/frontend/src/shared/hooks/useMutation.test.ts new file mode 100644 index 000000000..2a69bf23b --- /dev/null +++ b/frontend/src/shared/hooks/useMutation.test.ts @@ -0,0 +1,46 @@ +import { renderHook, act, waitFor } from '@testing-library/react'; +import { useMutation } from './useMutation'; + +describe('useMutation 테스트', () => { + let mutateFn: jest.Mock; + + beforeEach(() => { + mutateFn = jest.fn(); + }); + + test('fetch가 성공했을 경우, isLoading 은 false, data는 mockData, error은 null이다.', async () => { + const mockData = { key: 'value' }; + mutateFn.mockResolvedValueOnce(mockData); + const { result } = renderHook(() => useMutation(mutateFn)); + + act(() => { + result.current.mutateData(); + }); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toEqual(mockData); + expect(result.current.error).toBe(null); + }); + }); + + test('fetch가 실패했을 경우, isLoading 은 false, datas는 null, error은 mockError다.', async () => { + const mockError = { message: 'An error occurred' }; + mutateFn.mockRejectedValueOnce(mockError); + const { result } = renderHook(() => useMutation(mutateFn)); + + act(() => { + result.current.mutateData(); + }); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isLoading).toBe(false); + expect(result.current.data).toBe(null); + expect(result.current.error).toEqual(mockError); + }); + }); +}); diff --git a/frontend/src/shared/utils/formatOrdinals.test.ts b/frontend/src/shared/utils/formatOrdinals.test.ts new file mode 100644 index 000000000..b3a3641a9 --- /dev/null +++ b/frontend/src/shared/utils/formatOrdinals.test.ts @@ -0,0 +1,23 @@ +import formatOrdinals from '@/shared/utils/formatOrdinals'; + +describe('formatOrdinals', () => { + test('숫자 1은 1st를 반환한다.', () => { + expect(formatOrdinals(1)).toBe('1st'); + }); + + test('숫자 2은 1nd를 반환한다.', () => { + expect(formatOrdinals(2)).toBe('2nd'); + }); + + test('숫자 3은 1rd를 반환한다.', () => { + expect(formatOrdinals(3)).toBe('3rd'); + }); + + test('숫자 4은 4th를 반환한다.', () => { + expect(formatOrdinals(4)).toBe('4th'); + }); + + test('숫자 11은 11th를 반환한다.', () => { + expect(formatOrdinals(11)).toBe('11th'); + }); +});