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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:16:05