Jest测试React Here Map组件报H.util.Cache#setMaxSize错误
问题背景
在React项目中测试Here Map组件,相关配置严格遵循官方指南,生产环境功能运行完全正常,项目使用Babel对JS依赖包@here/maps-api-for-javascript做转译处理。
运行测试用例时抛出如下报错:
InvalidArgumentError: H.util.Cache#setMaxSize (Argument #0 0) 34 | }) 35 | const layers = platform.createDefaultLayers() > 36 | const map = new H.Map(ref.current, layers.vector.normal.map, { | ^ 37 | pixelRatio: window.devicePixelRatio || 1, 38 | center: { lat: 6.6111, lng: 20.9394 }, 39 | zoom: 5
现有jest.config.js配置如下:
{ "bail": true, "collectCoverageFrom": ["**/src/**/*.ts?(x)", "!**/src/index.tsx"], "moduleNameMapper": { "\\.(css|less|scss)$": "identity-obj-proxy" }, "verbose": true, "preset": "ts-jest", "setupFiles": ["./scripts/env-setup.ts"], "setupFilesAfterEnv": ["./scripts/jest.setup.ts", "jest-canvas-mock"], "testMatch": ["**/src/**/*.test.ts?(x)"], "transformIgnorePatterns": ["/node_modules/(?!(@here|bar)/)"], "transform": { "^.+\\.js?$": "babel-jest" } }
测试用例逻辑非常简单,仅包含expect(mapWrapper).toBeTruthy()断言,无明确排查方向。
排查与解决方案
- 根因定位:该报错本质是两个问题叠加导致:一是Jest默认使用的JSDOM测试环境无法完整提供Here Maps初始化依赖的浏览器端Canvas、元素尺寸、WebGL相关API,导致内部计算缓存默认大小时拿到非法值0;二是当前配置对
@here/maps-api-for-javascript做了多余的Babel转译,破坏了包内部的默认参数逻辑。 - 推荐修复方案(单元测试场景最优解):单元测试不需要真实初始化第三方地图实例,直接mock
@here/maps-api-for-javascript模块即可,从根源避免环境兼容问题。
在项目__mocks__目录下新建对应模块的mock文件:
Jest会自动加载该mock替换真实的地图模块,不需要额外修改业务代码。// __mocks__/@here/maps-api-for-javascript.js class MockHMap { constructor() {} // 按需补充组件中用到的Map实例方法即可 setCenter() {} setZoom() {} addObject() {} removeObject() {} } const mockPlatformInstance = { createDefaultLayers: () => ({ vector: { normal: { map: {} } } }) } export default { Map: MockHMap, service: { Platform: class { constructor() { return mockPlatformInstance } } } } - 若需要在测试中运行真实地图逻辑,按以下步骤调整配置:
- 移除对
@here/maps-api-for-javascript的Babel转译:该包本身已经是编译完成的可运行JS,额外转译会破坏内部逻辑,直接把@here从transformIgnorePatterns的转译白名单中移除即可。 - 补全JSDOM缺失的API mock:在jest setup文件中补充地图初始化依赖的浏览器API模拟,比如给挂载地图的DOM节点添加
offsetWidth、offsetHeight默认值,补全Canvas上下文的mock,确保内部计算缓存、尺寸参数时不会拿到0值。
- 移除对
- 临时验证方案:如果只是快速验证报错来源,可以在初始化H.Map时手动传入缓存配置绕过参数校验:
该方案仅用于定位问题,后续还会触发其他JSDOM环境缺失API的报错,不建议作为长期修复方案。const map = new H.Map(ref.current, layers.vector.normal.map, { pixelRatio: window.devicePixelRatio || 1, center: { lat: 6.6111, lng: 20.9394 }, zoom: 5, cacheSize: 1024 // 手动指定合法缓存大小,覆盖默认计算出的0值 })
内容的提问来源于stack exchange,提问作者ancsjs
相关产品推荐
相关产品推荐

