Angular中Echarts(setOption) Jest单元测试报错求助
解决Angular单元测试中Echarts初始化的"dpr"未定义错误
针对你遇到的问题,提供几个可行的解决方案,按优先级尝试:
1. 确保DOM元素在组件创建前完成模拟
ngAfterViewInit会在第一次fixture.detectChanges()时触发,如果你是在组件初始化后才添加DOM元素,document.getElementById('line-chart')会返回undefined,导致Echarts初始化失败。调整模拟时机:
beforeEach(() => { // 先创建并挂载DOM元素 const chartEl = document.createElement('div'); chartEl.id = 'line-chart'; document.body.appendChild(chartEl); // 再初始化测试环境 TestBed.configureTestingModule({ declarations: [YourTargetComponent] }); fixture = TestBed.createComponent(YourTargetComponent); component = fixture.componentInstance; }); afterEach(() => { // 测试后清理DOM,避免污染其他用例 const chartEl = document.getElementById('line-chart'); if (chartEl) document.body.removeChild(chartEl); });
2. Mock Echarts实例,跳过真实初始化逻辑
单元测试无需验证Echarts的渲染逻辑,直接mock整个echarts模块,避免真实初始化带来的依赖问题:
// 在测试文件顶部全局mock echarts jest.mock('echarts', () => ({ init: jest.fn(() => ({ setOption: jest.fn(), dispose: jest.fn() })), // 组件用到的其他Echarts方法也一并mock }));
这样initChartOption中调用echarts.init时会拿到模拟实例,setOption不会执行真实逻辑,自然不会触发dpr相关错误。
3. 完善模拟DOM元素的必要属性
Echarts初始化时会读取元素的尺寸和设备像素比,给模拟元素补充相关方法和样式:
beforeEach(() => { const chartEl = document.createElement('div'); chartEl.id = 'line-chart'; // 模拟元素尺寸 chartEl.getBoundingClientRect = jest.fn(() => ({ width: 500, height: 300, top: 0, left: 0 })); // 设置基础样式 chartEl.style.width = '500px'; chartEl.style.height = '300px'; document.body.appendChild(chartEl); // 组件初始化逻辑... });
4. 检查jest-canvas-mock的全局引入
确保jest-canvas-mock是全局生效的,在jest.config.js中配置:
module.exports = { setupFilesAfterEnv: ['jest-canvas-mock'], // 其他jest配置项 };
如果仅在单个测试文件中导入,可能无法覆盖Echarts初始化时的canvas依赖。
内容的提问来源于stack exchange,提问作者suli
相关产品推荐
相关产品推荐

