React Native测试Axios hook时Jest报globalObj.setTimeout is not a function错误
错误根因
该报错属于测试环境全局API适配问题,和你的业务代码逻辑无关,触发原因有三个:
- Expo项目误用了原生React Native的Jest预设,没有正确加载React Native环境的全局定时器API
- 混用了旧版
react-hooks-testing-library和新版@testing-library/react-native的API,两者的定时器处理逻辑冲突 - 测试用例中多余的
act嵌套导致测试库在微任务清理阶段调用了未定义的setTimeout,而你的断言在异步逻辑执行完成就已经通过,所以会出现断言全过但测试失败的情况
解决方案
按以下步骤调整即可解决:
- 第一步:修改package.json中的Jest配置
把原有的jest配置替换为:
"jest": { "preset": "jest-expo", "setupFilesAfterEnv": ["@testing-library/jest-native/extend-expect"] }
- 第二步:移除冗余依赖
卸载已经废弃的react-hooks-testing-library,执行命令:npm uninstall react-hooks-testing-library或者yarn remove react-hooks-testing-library - 第三步:修改测试用例代码
新版@testing-library/react-native已经内置renderHook能力,调整后的测试代码如下:
import { renderHook, waitFor } from "@testing-library/react-native"; import axios from "axios"; import { useAPI } from "../../Hooks/useAPI"; jest.mock("axios"); const mockData = {data: [{"test":"test"}]}; const getTestData = () => axios.get("/testEndpoint"); describe("fetch api data", () => { describe("on success", () => { it("should set data to test data and set isLoading false", async () => { axios.get.mockResolvedValueOnce(mockData); const { result } = renderHook(() => useAPI(getTestData)); await waitFor(() => { expect(result.current[0]).toEqual(false); }) const {data: expectedData} = mockData; expect(result.current[1]).toEqual(expectedData); expect(result.current[2]).toEqual(null); }) }) })
- 可选兜底方案:如果调整后仍有报错,在测试文件顶部添加全局定时器polyfill:
global.setTimeout = global.setTimeout || (callback => callback()); global.setImmediate = global.setImmediate || (callback => callback());
内容的提问来源于stack exchange,提问作者Dzone64
相关产品推荐
相关产品推荐

