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

如何正确测试自定义Leaflet图标函数?解决测试匹配报错问题

自定义Leaflet图标函数的测试问题解决

问题重现

自定义图标函数addSimpleIcon实现代码:

addSimpleIcon(
    iconUrl,
    iconRetinaUrl: string = null,
    iconHeight: number = 20,
    iconWidth: number = 20
  ): Icon {
    const icon: Icon = L.icon({
      iconUrl,
      iconRetinaUrl,
      iconSize: [iconWidth, iconHeight], 
      shadowSize: [0, 0],
      iconAnchor: [iconWidth / 2, iconHeight / 2], 
      shadowAnchor: [0, 0], 
      popupAnchor: [0, 0]
    });
    return icon;
  }

编写的测试用例:

it('should return a simple icon with properties', () => {
    const test = 'testUrl';
    const anotherTestString = 'test';
    const testHeight = 2;
    const testWidth = 2;
    expect(
      service.addSimpleIcon(test, anotherTestString, testHeight, testWidth)
    ).toEqual(anotherTestIcon);
  });

预期匹配的anotherTestIcon定义:

const anotherTestIcon: Icon = L.icon({
    iconUrl: 'testUrl',
    iconRetinaUrl: 'test',
    iconSize: [2, 2],
    shadowSize: [0, 0],
    iconAnchor: [20 / 2, 20 / 2],
    shadowAnchor: [0, 0],
    popupAnchor: [0, 0]
  });

测试报错信息:

Expected $.options.iconAnchor[0] = 1 to equal 10.
Expected $.options.iconAnchor[1] = 1 to equal 10.

错误原因

测试预期对象anotherTestIcon的iconAnchor用了固定值20/2,但实际调用addSimpleIcon时传入的是testWidth=2和testHeight=2,函数会计算出iconAnchor=[1,1],和预期的[10,10]不匹配,导致测试失败。

修正测试用例

将anotherTestIcon的iconAnchor改为与传入参数匹配的计算值即可:

const anotherTestIcon: Icon = L.icon({
    iconUrl: 'testUrl',
    iconRetinaUrl: 'test',
    iconSize: [2, 2],
    shadowSize: [0, 0],
    iconAnchor: [2 / 2, 2 / 2], // 或直接写[1,1]
    shadowAnchor: [0, 0],
    popupAnchor: [0, 0]
  });

更优测试方式

直接对比整个Leaflet Icon实例可能受隐藏属性干扰,推荐以下几种更稳妥的测试方式:

方式1:验证options对象

直接对比实例的options属性,避免无关属性影响:

it('should return a simple icon with correct properties', () => {
  const testUrl = 'testUrl';
  const testRetinaUrl = 'test';
  const testHeight = 2;
  const testWidth = 2;

  const resultIcon = service.addSimpleIcon(testUrl, testRetinaUrl, testHeight, testWidth);
  
  expect(resultIcon.options).toEqual({
    iconUrl: testUrl,
    iconRetinaUrl: testRetinaUrl,
    iconSize: [testWidth, testHeight],
    shadowSize: [0, 0],
    iconAnchor: [testWidth / 2, testHeight / 2],
    shadowAnchor: [0, 0],
    popupAnchor: [0, 0]
  });
});

方式2:逐个校验关键属性

只验证核心业务属性,减少测试脆弱性:

it('should set correct icon properties', () => {
  const testUrl = 'testUrl';
  const testRetinaUrl = 'test';
  const testHeight = 2;
  const testWidth = 2;

  const resultIcon = service.addSimpleIcon(testUrl, testRetinaUrl, testHeight, testWidth);
  
  expect(resultIcon.options.iconUrl).toBe(testUrl);
  expect(resultIcon.options.iconRetinaUrl).toBe(testRetinaUrl);
  expect(resultIcon.options.iconSize).toEqual([testWidth, testHeight]);
  expect(resultIcon.options.iconAnchor).toEqual([testWidth / 2, testHeight / 2]);
  expect(resultIcon.options.shadowSize).toEqual([0, 0]);
});

方式3:测试默认参数

补充测试函数的默认参数逻辑:

it('should use default values when parameters are not provided', () => {
  const resultIcon = service.addSimpleIcon('defaultUrl');
  
  expect(resultIcon.options.iconUrl).toBe('defaultUrl');
  expect(resultIcon.options.iconRetinaUrl).toBeNull();
  expect(resultIcon.options.iconSize).toEqual([20, 20]);
  expect(resultIcon.options.iconAnchor).toEqual([10, 10]);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:50:13