Jest测试中如何mock @react-google-maps/api的useJsApiLoader
现有写法的正确性判断
你当前的写法在组件仅使用useJsApiLoader、且只需要验证加载完成后的逻辑的场景下可以正常生效,但存在两个明显问题:
- 会完全覆盖
@react-google-maps/api的所有其他导出,如果后续组件中引入了GoogleMap、Marker、InfoWindow等该库提供的其他组件或工具方法,测试会直接抛出找不到对应导出的错误 - 返回值完全写死,无法覆盖加载中、加载失败等其他分支逻辑的测试场景,用例灵活性很差
更规范的Mock实现方案
推荐使用「保留原始库其他导出,仅Mock目标Hook」的写法,兼顾可维护性和用例灵活性:
jest.mock("@react-google-maps/api", () => { // 引入库的原始实现,保留非目标API的正常逻辑 const originalExports = jest.requireActual("@react-google-maps/api"); return { ...originalExports, // 仅替换useJsApiLoader为可配置的Jest Mock函数 useJsApiLoader: jest.fn(), }; });
这种写法下,你可以在不同测试用例中按需配置useJsApiLoader的返回值,覆盖所有业务分支:
- 模拟API加载完成状态(和你当前写法效果一致):
import { useJsApiLoader } from "@react-google-maps/api"; test("组件加载完成后正常渲染地图", () => { useJsApiLoader.mockReturnValue({ isLoaded: true, loadError: undefined, }); // 后续编写组件渲染、断言逻辑 });
- 模拟API加载中状态:
test("加载中状态显示loading提示", () => { useJsApiLoader.mockReturnValue({ isLoaded: false, loadError: undefined, }); // 断言loading组件正常渲染 });
- 模拟API加载失败状态:
test("加载失败显示错误提示", () => { useJsApiLoader.mockReturnValue({ isLoaded: false, loadError: new Error("Google Maps资源加载失败"), }); // 断言错误提示组件正常渲染 });
如果项目使用TypeScript,为了避免类型校验报错,可以将导入的hook转为Jest Mock类型再调用mock方法,写法为
(useJsApiLoader as jest.Mock).mockReturnValue(...)
如果你的组件确定不会用到该库的其他导出,原有写法也可以运行,但从可维护性角度不推荐,后续组件迭代新增其他库API的引入时测试会直接报错。
内容的提问来源于stack exchange,提问作者Rafael Hernandez
相关产品推荐
相关产品推荐

