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

如何使用Testing Library/Jest模拟触发react-leaflet-draw的onCreated事件

问题说明

使用React Testing Library/Jest对react-leaflet-draw中EditControl组件的onCreated事件处理函数编写单元测试时,最初的实现方案无法触发回调,未达到预期测试效果,需要找到可正确触发onCreated事件的编程式测试方案。

初始无效实现

测试用例代码

test('Polygon draw functionality', async () => {
  const drawHandler = jest.fn();
  const { getByText, getByTestId, getAllByTestId, queryAllByTestId } = render(
  <Map
    data={mapData}
    onDraw={drawHandler}
  ></Map>,
  {}
);
  let e = document.createEvent('Event');
  e.initEvent('click', true, true);
  let cb = document.getElementsByClassName('leaflet-draw-draw-polygon');
  cb[0].dispatchEvent(e);
  expect(drawHandler).toHaveBeenCalled();
});

被测组件代码(Map.js)

// 其余组件逻辑省略
<FeatureGroup>
        <EditControl
          position='topright'
          onCreated={props.onDraw}
          draw={{
            polyline: false,
            polygon: true,
            rectangle: false,
            circle: false,
            marker: false,
            circlemarker: false,
          }}
        />
      </FeatureGroup>
// 其余组件逻辑省略
可行测试方案

原方案无效的核心原因:点击多边形绘制按钮仅会激活绘制工具状态,不会直接触发onCreated回调。onCreated的触发时机是用户完成全部图形绘制操作、闭合多边形之后,单纯触发工具按钮的点击事件完全达不到回调触发条件。

不建议尝试模拟全链路DOM点击来走完绘制流程:Leaflet的绘制逻辑绑定在地图实例内部事件上,JSDOM环境下纯DOM事件模拟无法覆盖内部坐标计算、图形生成的完整逻辑,测试稳定性极差,维护成本极高。

正确的单元测试实现思路如下:

  • react-leaflet-draw的onCreated本质是监听Leaflet地图实例上的原生draw:created事件,测试时直接获取地图实例,手动派发符合格式的对应事件即可准确触发绑定的回调,不需要模拟复杂的用户绘制操作。
  • 完整的用户交互绘制流程验证属于E2E测试范畴,建议放到Cypress、Playwright这类E2E工具中实现,不要在Jest+JSDOM的单元测试环境下做这类强依赖真实DOM渲染、地理坐标计算的交互模拟。

修正后的测试用例参考:

test('Polygon draw functionality', async () => {
  const drawHandler = jest.fn();
  render(
    <Map
      data={mapData}
      onDraw={drawHandler}
    ></Map>
  );

  // 等待地图容器渲染完成
  await waitFor(() => {
    expect(document.querySelector('.leaflet-container')).toBeInTheDocument();
  });
  // 获取Leaflet地图实例,若使用react-leaflet v3+版本,也可通过测试专用props从组件内部暴露实例,避免读取DOM私有属性
  const mapInstance = document.querySelector('.leaflet-container')._leaflet_map;

  // 构造draw:created事件参数,模拟多边形绘制完成的场景
  const testPolygonLayer = L.polygon([
    [51.509, -0.08],
    [51.503, -0.06],
    [51.51, -0.047]
  ]);
  mapInstance.fire('draw:created', {
    layer: testPolygonLayer,
    layerType: 'polygon'
  });

  // 验证回调触发逻辑
  expect(drawHandler).toHaveBeenCalledTimes(1);
  // 可按需增加回调参数校验
  expect(drawHandler.mock.calls[0][0].layerType).toBe('polygon');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:15:11