如何在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
相关产品推荐
相关产品推荐

