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

Jest测试ReactLeaflet地图组件时触发useLeafletContext上下文错误

排查Jest测试React-Leaflet组件时的LeafletContext缺失问题
  • 确保测试中用正确包裹组件
    你手动创建LeafletContext无效的核心原因是:React-Leaflet的useLeafletContext()依赖的是<MapContainer>内部自动生成的上下文,而非手动实例的LeafletContext。测试时必须将MapLayout放在<MapContainer>的子树中,且传入必填的center和zoom属性(哪怕是测试用的假值):

    import { render } from '@testing-library/react';
    import { MapContainer } from 'react-leaflet';
    import MapLayout from './MapLayout';
    
    test('MapLayout renders without context error', () => {
      render(
        <MapContainer center={[0, 0]} zoom={1} style={{ height: '400px' }}>
          <MapLayout />
        </MapContainer>
      );
    });
    
  • 适配Leaflet Routing Machine的测试环境
    Leaflet Routing Machine(LRM)依赖全局Leaflet实例,Jest环境中可能未正确加载相关依赖:

    1. 在测试文件顶部导入Leaflet和LRM,确保全局L对象可用:
      import L from 'leaflet';
      import 'leaflet-routing-machine';
      global.L = L;
      
    2. 模拟LRM的核心组件,避免测试时依赖外部路由服务:
      jest.mock('leaflet-routing-machine', () => {
        return {
          Routing: {
            Control: jest.fn().mockReturnValue({
              addTo: jest.fn(),
              remove: jest.fn()
            })
          }
        };
      });
      
  • 检查组件内部的Context使用范围
    确认MapLayout及其所有子组件中,使用useLeafletContext()的部分都处于<MapContainer>的包裹范围内。如果组件内部有条件渲染的子组件未被包裹,也会触发该错误。

  • 排查Jest配置的模拟冲突
    检查jest.config.js或测试文件中的模块模拟,避免错误地mock了react-leaflet的核心组件:

    • 如果之前用了jest.mock('react-leaflet'),需确保模拟的<MapContainer>能正确提供上下文,或者直接移除该mock,改用真实的MapContainer包裹测试组件。
  • 补全测试环境的全局对象
    Leaflet依赖浏览器环境的一些全局属性,Jest的jsdom环境可能缺失这些属性,可在setupFilesAfterEnv中补充:

    // setupTests.js
    global.navigator.geolocation = {
      getCurrentPosition: jest.fn().mockResolvedValue({ coords: { latitude: 0, longitude: 0 } })
    };
    // 若需要,补充Leaflet依赖的其他window属性
    
  • 模拟Leaflet的DOM操作
    测试时无需渲染真实的地图瓦片,可mock Leaflet的核心DOM相关方法,避免环境报错:

    jest.mock('leaflet', () => {
      const mockMap = {
        setView: jest.fn(),
        addLayer: jest.fn(),
        removeLayer: jest.fn()
      };
      return {
        map: jest.fn().mockReturnValue(mockMap),
        tileLayer: jest.fn().mockReturnValue({ addTo: jest.fn() }),
        icon: jest.fn(),
        marker: jest.fn().mockReturnValue({ addTo: jest.fn() })
      };
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:43:18