You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:05:35