import { QueryClient, QueryClientProvider, useQuery, } from '@tanstack/react-query'; import { useSearchParams } from 'react-router-dom'; import { renderHook } from '@testing-library/react'; import { URLSearchParams } from 'url'; // Services import { getAllUsers } from '@service/userServices'; // Hooks import { useUsers } from '../useUsers'; jest.mock('react-router-dom', () => ({ useSearchParams: jest.fn(), })); jest.mock('@tanstack/react-query', () => ({ ...jest.requireActual('@tanstack/react-query'), useQuery: jest.fn(), })); jest.mock('@service/userServices', () => ({ getAllUsers: jest.fn(), })); describe('useUsers hook', () => { let queryClient: QueryClient; beforeEach(() => { jest.clearAllMocks(); queryClient = new QueryClient(); (queryClient.prefetchQuery as jest.Mock) = jest.fn(); }); test('Should fetch data successful', async () => { const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 3 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=1'), new URLSearchParams('search=test'), ]); (useQuery as jest.Mock).mockImplementation(({ queryFn }) => { const result = { isLoading: false, error: {}, data: sampleDate, }; queryFn(); return result; }); (getAllUsers as jest.Mock).mockResolvedValue(sampleDate); const { result } = renderHook(() => useUsers(), { wrapper: ({ children }) => ( {children} ), }); expect(result.current.users).toEqual(sampleDate.data); expect(result.current.count).toEqual(sampleDate.count); }); test('Should prefetch the second page when in the first page', async () => { const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 7 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=1'), new URLSearchParams('search=test'), ]); (useQuery as jest.Mock).mockImplementation(({ queryFn }) => { const result = { isLoading: false, error: {}, data: sampleDate, }; queryFn(); return result; }); (getAllUsers as jest.Mock).mockResolvedValue(sampleDate); renderHook(() => useUsers(), { wrapper: ({ children }) => ( {children} ), }); expect(queryClient.prefetchQuery).toHaveBeenCalledTimes(1); expect(queryClient.prefetchQuery).toHaveBeenCalledWith({ queryKey: ['users', 'id', 'asc', '', 2], queryFn: expect.any(Function), }); }); test('Should prefetch the previous page and next page when in the second page', async () => { const sampleDate = { data: [{ id: 1, name: 'User 1' }], count: 12 }; (useSearchParams as jest.Mock).mockReturnValue([ new URLSearchParams('page=2'), new URLSearchParams('search=test'), ]); (useQuery as jest.Mock).mockImplementation(({ queryFn }) => { const result = { isLoading: false, error: {}, data: sampleDate, }; queryFn(); return result; }); (getAllUsers as jest.Mock).mockResolvedValue(sampleDate); renderHook(() => useUsers(), { wrapper: ({ children }) => ( {children} ), }); expect(queryClient.prefetchQuery).toHaveBeenCalledTimes(2); expect(queryClient.prefetchQuery).toHaveBeenCalledWith({ queryKey: ['users', 'id', 'asc', '', 3], queryFn: expect.any(Function), }); expect(queryClient.prefetchQuery).toHaveBeenCalledWith({ queryKey: ['users', 'id', 'asc', '', 1], queryFn: expect.any(Function), }); }); });