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

如何在Jest+React Testing Library中Mock Leaflet的LatLngToLayerPoint方法?

自定义Mock Leaflet 实现latLngToLayerPoint方法用于测试

我之前也碰到过一模一样的问题,默认的react-leaflet Mock确实没覆盖全Leaflet的地图方法,下面给你两个实用的解决方案,按需选就行:

方案一:在单个测试文件中临时扩展Mock

如果只是少数几个测试需要用到这个方法,可以直接在测试文件顶部覆盖leaflet模块的Mock:

jest.mock('leaflet', () => {
  // 先获取原有Mock的内容,避免丢失其他已实现的方法
  const originalLeafletMock = jest.requireActual('leaflet');
  
  return {
    ...originalLeafletMock,
    // 重写Map类的Mock,添加latLngToLayerPoint方法
    Map: jest.fn(() => ({
      // 保留原有Mock的方法,比如setView、getZoom等
      setView: jest.fn(),
      getZoom: jest.fn(() => 10),
      getCenter: jest.fn(() => ({ lat: 0, lng: 0 })),
      // 自定义坐标转换逻辑,这里可以根据测试需求返回固定值或动态计算
      latLngToLayerPoint: jest.fn((latlng) => {
        // 示例:把经纬度乘以10转换为像素坐标
        return { x: latlng.lat * 10, y: latlng.lng * 10 };
      }),
      // 其他你需要的地图方法也可以在这里添加
    })),
    // 如果组件用到了LatLng类,确保Mock正确
    LatLng: jest.fn((lat, lng) => ({ lat, lng })),
  };
});

这样你的组件调用map.latLngToLayerPoint()时,就会使用这个自定义的Mock方法了。

方案二:创建全局复用的自定义Mock文件

如果多个测试文件都需要用到这个方法,建议在项目根目录下创建__mocks__/leaflet.js文件(没有的话新建),基于react-leaflet提供的Mock修改:

// 复制原react-leaflet Mock的基础内容,然后添加需要的方法
export const Map = jest.fn(() => ({
  setView: jest.fn(),
  panTo: jest.fn(),
  zoomIn: jest.fn(),
  zoomOut: jest.fn(),
  getZoom: jest.fn(() => 10),
  getBounds: jest.fn(() => ({
    getSouthWest: jest.fn(() => LatLng(0, 0)),
    getNorthEast: jest.fn(() => LatLng(0, 0)),
  })),
  getCenter: jest.fn(() => LatLng(0, 0)),
  // 添加latLngToLayerPoint方法,自定义返回逻辑
  latLngToLayerPoint: jest.fn((latlng) => {
    // 这里可以写死固定像素值,或者根据输入的经纬度动态生成
    return { x: 150, y: 250 };
  }),
}));

export const TileLayer = jest.fn(() => ({
  setUrl: jest.fn(),
}));

export const Marker = jest.fn(() => ({
  setLatLng: jest.fn(),
}));

export const LatLng = jest.fn((lat, lng) => ({ lat, lng }));

// 其他Leaflet类的Mock保持原内容即可

Jest会自动识别这个全局Mock文件,所有测试都会使用这个自定义版本,不用每个文件重复写Mock代码。

测试验证技巧

你可以在测试中断言这个方法是否被正确调用,比如:

test('组件正确调用坐标转换方法', () => {
  render(<YourLeafletMapComponent />);
  // 获取Map类的实例
  const mockMap = Map.mock.instances[0];
  // 断言方法被调用
  expect(mockMap.latLngToLayerPoint).toHaveBeenCalled();
  // 或者断言调用时传入的参数
  expect(mockMap.latLngToLayerPoint).toHaveBeenCalledWith(expect.objectContaining({
    lat: 51.505,
    lng: -0.09,
  }));
  // 也可以验证返回值
  expect(mockMap.latLngToLayerPoint({ lat: 51.505, lng: -0.09 })).toEqual({ x: 515.05, y: -9 });
});

注意:Leaflet原生的方法名是latLngToLayerPoint(小驼峰),如果你的组件里写的是LatLngToLayerPoint(大驼峰),记得把Mock里的方法名也改成对应大驼峰的形式哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:42:45