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

如何测试在useEffect中调用模拟Geolocation的React自定义Hook?

解决方案

首先要确保正确模拟navigator.geolocation.getCurrentPosition,让它能触发回调更新状态,再结合React Testing Library的waitFor等待状态更新完成,就能解决常规测试下无法获取异步结果的问题。

1. 完善模拟逻辑

在测试文件顶部添加全局模拟代码,让getCurrentPosition立即执行成功回调:

beforeAll(() => {
  const mockGeolocation = {
    getCurrentPosition: jest.fn((success) =>
      Promise.resolve().then(() =>
        success({
          coords: {
            latitude: 40.7128,
            longitude: -74.0060,
            accuracy: 100,
            altitude: null,
            altitudeAccuracy: null,
            heading: null,
            speed: null,
          },
        })
      )
    ),
  };

  global.navigator.geolocation = mockGeolocation;
});

afterAll(() => {
  jest.restoreAllMocks();
});

2. 修改测试代码,等待状态更新

setCoords是异步更新状态的操作,直接断言会拿到初始的undefined,用waitFor可以轮询断言直到状态更新完成:

import { renderHook, waitFor } from '@testing-library/react';
import useGeolocation from './useGeolocation';

it('should return non-empty coords', async () => {
  const { result } = renderHook(() => useGeolocation());

  await waitFor(() => {
    expect(result.current).not.toBeUndefined();
  });

  // 可额外断言具体坐标值验证正确性
  expect(result.current?.latitude).toBe(40.7128);
  expect(result.current?.longitude).toBe(-74.0060);
});

问题原因说明

调试模式下代码执行速度慢,状态更新有足够时间完成;但常规测试运行时代码同步执行,状态还未更新就触发了断言。waitFor会持续检查断言条件,直到满足或超时,刚好适配这种异步状态更新场景。

内容的提问来源于stack exchange,提问作者sKopheK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:35:38