使用Jest测试Chart.js组件时遇TypeError: auto_1.default不是构造函数
问题
我用chart.js/auto导入创建饼图的组件运行正常,但执行spec.ts测试文件时,在new Chart代码行出现TypeError: auto_1.default is not a constructor错误。
使用版本:
- chart.js 3.9.1
- jest-canvas-mock 2.4.0
- ng-mocks 14.2.3
组件代码片段(可正常运行):
import Chart from 'chart.js/auto' // ... myChart: Chart; createChart(){ this.myChart = new Chart(this.ctx, this.config); }
测试文件spec.ts代码片段:
// ... import Chart from 'chart.js/auto'; describe('myComponent', () => { let component: myComponent; let fixture: ComponentFixture<myComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [myComponent, MockComponent(otherComponent)], imports: [myModules], providers: [Utilities, Services] }).compileComponents(); fixture = TestBed.createComponent(myComponent); component = fixture.componentInstance; fixture.detectChanges(); })); describe('createChart()', () => { it('should exist', () => { component.createChart(); expect(component.createChart).toBeCalled(); }); }); });
错误信息:
MyComponent > createChart() > should exist TypeError: auto_1.default is not a constructor this.myChart = new Chart(this.ctx, this.config); ^
为何组件可正常创建并使用图表,但Jest却不将其识别为构造函数?
解决方案
这个问题的核心是Jest对ES模块的处理逻辑和Chart.js的导出方式不匹配导致的。
原因
Chart.js 3.x的chart.js/auto采用命名导出而非默认导出,但组件代码中使用了默认导入的写法。Angular的构建环境(如Webpack)会自动兼容这种导入差异,但Jest没有做同样的兼容处理,导致导入的Chart是一个包含构造函数属性的对象,而非构造函数本身,因此new Chart()会触发错误。
解决办法
1. 修正导入方式
将组件和测试文件中的导入改为命名导入,确保在两种环境下都能正确获取构造函数:
import { Chart } from 'chart.js/auto';
2. 为Jest添加模块映射(可选)
如果不想修改现有导入代码,可以在jest.config.js中添加模块映射,将默认导出指向命名导出:
module.exports = { // ...其他Jest配置 moduleNameMapper: { 'chart.js/auto': '<rootDir>/src/mocks/chart.js', }, };
对应的mock文件src/mocks/chart.js内容如下:
import { Chart } from 'chart.js'; export default Chart;
3. 确保jest-canvas-mock正确配置
确认jest-canvas-mock已加入setupFilesAfterEnv,避免Canvas相关的额外错误:
module.exports = { setupFilesAfterEnv: ['jest-canvas-mock'], };
内容的提问来源于stack exchange,提问作者THE KID
相关产品推荐
相关产品推荐

