React-Jest测试报错:TypeError: refetch is not a function
问题:Jest测试中调用react-query的refetch报TypeError错误
组件内使用useFocusEffect钩子调用react-query返回的refetch方法,应用运行正常,但Jest单元测试时抛出TypeError: refetch is not a function错误。已尝试mockrefetch函数并作为返回值传入,但问题未解决。
组件代码(App.js)
const { data, refetch } = useStudents( student?.id ); useFocusEffect( React.useCallback(() => { refetch(); }, [refetch]) );
Jest测试代码
import { Home } from './Home'; jest.mock('hooks/Auth/useLoadAuthStudentsData', () => ({ useLoadAuthStudentData: jest.fn() })); jest.mock('hooks/Student/useStudents', () => ({ useStudents: jest.fn() })); jest.mock('@react-navigation/core', () => { return { ...jest.requireActual('@react-navigation/core'), useNavigation: jest.fn(() => ({})) }; }); const useLoadAuthStudentsData = userHook as ReturnType<typeof jest.fn>; const useStudents = tasksHook as ReturnType<typeof jest.fn>; const navContext = { isFocused: () => true, addListener: jest.fn(() => jest.fn()) }; const mockParams = { params: { studentId: 'studentId' } }; describe('Home', () => { beforeEach(() => { const refetchFunc = jest.fn(); useStudents.mockReturnValue({ data: Student.deserializeAsList(studentsStub), isLoading: false, isSuccess: true, isError: false, refetch: refetchFunc }); useLoadAuthStudentData.mockReturnValue({ data: studentStub }); }); const component = ( <NavigationContext.Provider value={navContext}> <Home route={mockParams} navigation={{ goBack: jest.fn() }} /> </NavigationContext.Provider> ); it('should render app without error', () => { expect(render(component)).toBeTruthy(); }); });
错误信息
● Home › should render screen without error TypeError: refetch is not a function 54 | useFocusEffect( 55 | React.useCallback(() => { > 56 | refetch(); | ^ 57 | }, [refetch]) 58 | ); 59 |
解决办法
1. 修复mock钩子的变量映射错误
测试代码中存在未定义变量的错误,导致useStudents没有正确指向mock的钩子函数:
// 原错误代码 const useLoadAuthStudentsData = userHook as ReturnType<typeof jest.fn>; const useStudents = tasksHook as ReturnType<typeof jest.fn>;
直接从mock模块导入并断言为jest.Mock类型:
// 修正后 import { useLoadAuthStudentData } from 'hooks/Auth/useLoadAuthStudentsData'; import { useStudents } from 'hooks/Student/useStudents'; // 断言为jest.Mock类型 const mockUseLoadAuthStudentsData = useLoadAuthStudentData as jest.Mock; const mockUseStudents = useStudents as jest.Mock;
然后在beforeEach中使用修正后的变量:
beforeEach(() => { const refetchFunc = jest.fn(); mockUseStudents.mockReturnValue({ data: Student.deserializeAsList(studentsStub), isLoading: false, isSuccess: true, isError: false, refetch: refetchFunc }); mockUseLoadAuthStudentsData.mockReturnValue({ data: studentStub }); });
2. 确保NavigationContext正确导入
测试中使用了NavigationContext,需确认已从@react-navigation/native正确导入:
import { NavigationContext } from '@react-navigation/native';
3. 验证mock返回值的设置时机
确保mockReturnValue在组件渲染前完成设置,beforeEach会在每个测试用例前执行,该时机是正确的,避免在组件定义后才设置mock。
内容的提问来源于stack exchange,提问作者SJaka
相关产品推荐
相关产品推荐

