Angular中Mapbox服务Jest单元测试报错TextDecoder未定义的解决咨询
解决Angular Jest测试中Mapbox GL JS的TextDecoder未定义问题
问题原因
Mapbox GL JS是为浏览器环境设计的,它依赖浏览器提供的TextDecoder、DOM元素等API。而Jest运行在Node.js环境中,这些API默认不存在,所以当测试代码导入mapbox-gl时就会抛出ReferenceError: TextDecoder is not defined的错误。
解决方案
推荐两种方案,优先选择模拟Mapbox模块的方式,因为单元测试不需要真实渲染地图,只需要验证服务的逻辑。
方案1:模拟Mapbox GL模块(推荐)
在你的mapbox.service.spec.ts中,用Jest的jest.mock方法模拟整个mapbox-gl模块,避免真实导入依赖浏览器环境的代码:
import { inject, TestBed } from '@angular/core/testing'; import { MapboxService } from './mapbox.service'; // 模拟mapbox-gl模块 jest.mock('mapbox-gl', () => ({ Map: jest.fn().mockImplementation(() => ({ // 如果你的服务中调用了Map实例的方法(比如on、remove、flyTo等),可以在这里添加对应的模拟实现 on: jest.fn(), remove: jest.fn() })) })); describe('Service: Mapbox', () => { beforeEach(() => { TestBed.configureTestingModule({ providers: [MapboxService], }); }); it('should be created', inject([MapboxService], (service: MapboxService) => { expect(service).toBeTruthy(); // 还可以验证Map构造函数是否被调用 const mapboxgl = require('mapbox-gl'); expect(mapboxgl.Map).toHaveBeenCalled(); })); });
这种方式不仅解决了环境依赖问题,还能让测试运行更快,同时可以验证Map实例的创建逻辑。
方案2:补全Node.js环境缺失的API
如果你确实需要在测试中使用真实的Mapbox实例,可以通过补全Node环境中缺失的浏览器API来解决:
- 首先安装
@types/node以获取Node.js API的类型声明:
npm install --save-dev @types/node # 或者用yarn yarn add -D @types/node
- 修改
setup.jest.ts文件,替换之前的错误代码:
import 'jest-preset-angular/setup-jest'; // 从util模块导入TextEncoder和TextDecoder(兼容低版本Node.js) import { TextEncoder, TextDecoder } from 'util'; // 使用globalThis替代global,避免Angular Jest环境中的类型错误 globalThis.TextEncoder = TextEncoder; globalThis.TextDecoder = TextDecoder;
为什么之前的方案出错?
node:util是Node.js 16+才支持的导入路径,如果你的Node版本低于16,需要改用util。- Angular的Jest环境中推荐使用
globalThis而不是global,后者会触发类型未定义的错误。
内容的提问来源于stack exchange,提问作者Maksat Madeniyetov
相关产品推荐
相关产品推荐

