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

React中如何Mock地理定位API自定义Hook以完成测试?

如何正确Mock地理定位API测试自定义Hook

你的自定义Hook通过navigator.geolocation获取位置并更新状态,但当前的Mock未触发回调导致测试无法验证状态变化。以下是符合最佳实践的Mock方案,覆盖你需要的三个测试目标:

一、完善地理定位API的Mock逻辑

基础Mock框架可以保留,但需要让getCurrentPosition主动调用传入的成功/错误回调,以此触发Hook内的setCoords。

1. 模拟成功定位场景

通过mockImplementation让Mock调用成功回调,传入模拟的位置数据,验证状态是否正确更新:

import { renderHook } from '@testing-library/react-hooks';
import useGeoLocAPI from './useGeoLocAPI';

const mockPosition = {
  coords: {
    latitude: 40.7128,
    longitude: -74.0060
  }
};

beforeEach(() => {
  global.navigator.geolocation.getCurrentPosition.mockClear();
});

test('成功获取位置时,状态被正确设置', () => {
  global.navigator.geolocation.getCurrentPosition.mockImplementation((success) => {
    success(mockPosition);
  });

  const { result } = renderHook(() => useGeoLocAPI());

  // 断言状态值与结构
  expect(result.current[0]).toEqual({
    lat: mockPosition.coords.latitude,
    long: mockPosition.coords.longitude
  });
  // 断言API被调用
  expect(global.navigator.geolocation.getCurrentPosition).toHaveBeenCalled();
});

2. 模拟定位失败场景

触发错误回调,验证错误处理逻辑是否生效:

test('定位失败时,错误信息被正确打印', () => {
  const mockError = { message: '用户拒绝定位权限' };
  const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();

  global.navigator.geolocation.getCurrentPosition.mockImplementation((_, error) => {
    error(mockError);
  });

  const { result } = renderHook(() => useGeoLocAPI());

  // 断言错误处理执行
  expect(consoleErrorSpy).toHaveBeenCalledWith(mockError.message);
  // 断言状态保持初始值
  expect(result.current[0]).toBeNull();

  consoleErrorSpy.mockRestore();
});

二、验证状态结构

单独测试初始状态和成功后的状态结构:

test('初始状态为null', () => {
  global.navigator.geolocation.getCurrentPosition.mockImplementation(() => {});

  const { result } = renderHook(() => useGeoLocAPI());
  expect(result.current[0]).toBeNull();
});

test('成功获取位置后,状态包含lat和long数字类型字段', () => {
  global.navigator.geolocation.getCurrentPosition.mockImplementation((success) => {
    success({ coords: { latitude: 1, longitude: 2 } });
  });

  const { result } = renderHook(() => useGeoLocAPI());
  expect(result.current[0]).toHaveProperty('lat');
  expect(result.current[0]).toHaveProperty('long');
  expect(typeof result.current[0].lat).toBe('number');
  expect(typeof result.current[0].long).toBe('number');
});

关键注意事项

  • 需安装@testing-library/react-hooks依赖,用于测试自定义Hook的状态变化。
  • 每次测试前重置Mock,避免用例间的状态污染。
  • 不要直接MocksetState,通过触发真实业务逻辑(如地理定位回调)驱动状态更新,这是符合测试最佳实践的方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:20:44