Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Testing Angular and Chart JS

Currently I am receiving the following error in my jest unit test in an Angular application that is testing a component that uses ChartJS.

TypeError: auto_1.default is not a constructor

The chart/graph displays fine and I am able to switch between different datasets that feed into this presentation component from an external data source.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I have tried importing the Chart from 'chart.js/auto'; into the test, mocking various functions that create the chart and to no success. Importing ChartJS into a test file, or creating a new chart to test in the test does nothing and I still receive the same error.

The .spec file:

import { ComponentFixture, TestBed } from '@angular/core/testing'
import { GraphDisplayComponent } from './graph-display.component';


describe('GraphDisplayComponent', () => {
  let component: GraphDisplayComponent;
  let fixture: ComponentFixture<GraphDisplayComponent>;


  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [GraphDisplayComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(GraphDisplayComponent);
    component = fixture.componentInstance;

    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

The .ts of the component

import {
  Component,
  ElementRef,
  Input,
  OnInit,
  ViewChild,
} from '@angular/core';
import Chart from 'chart.js/auto';

@Component({
  selector: 'app-graph-display',
  templateUrl: './graph-display.component.html',
  styleUrls: ['./graph-display.component.scss'],
})
export class GraphDisplayComponent implements OnInit {
  @Input() chartData: any;
  @ViewChild('canvas', { static: true }) canvas!: ElementRef;
  chart!: any;

  ngOnInit() {
    this.chart = new Chart(this.canvas.nativeElement, this.chartData);
  }

}


>Solution :

The error TypeError: auto_1.default is not a constructor you’re encountering usually stems from a problem with module import/export semantics. The problem is likely that Jest, under its default configuration with Angular, uses CommonJS to handle module imports/exports. When combined with certain libraries or versions of libraries (like Chart.js) that are distributed using ES modules, this mismatch can lead to errors.

A few steps you can take to fix this:

  1. Jest Configuration

    Ensure that your Jest configuration is properly set up to handle ES modules. A package named jest-preset-angular helps set up Angular with Jest. If you’re not already using it, I recommend trying it.

  2. Mocking Chart.js

    In many cases, you might not want actually to instantiate or run the real Chart.js in your tests. Instead, you can mock it. This can avoid the error entirely and make your test run faster.

    At the top of your .spec file, before any other imports:

    jest.mock('chart.js/auto', () => ({
      default: jest.fn().mockImplementation(() => ({
        // any mock methods or properties you need
      }))
    }));
    

    This mocks out the Chart constructor so it doesn’t do anything. If you need to test that the constructor is called, or that methods on the chart instance are called, you can add more to the mock.

  3. ES Module Handling

    If you want to handle ES modules directly, you might need to update your Jest config and use Babel to help Jest understand ES modules. This is a more involved solution, but can be necessary for some setups. Here’s a simplified version:

    1. Install the necessary Babel packages:

      npm install --save-dev @babel/preset-env @babel/preset-typescript
      
    2. Create or update a .babelrc file:

      {
        "presets": [
          "@babel/preset-env",
          "@babel/preset-typescript"
        ]
      }
      
    3. Update your Jest configuration to use Babel:

      {
        "transform": {
          "^.+\\.tsx?$": "babel-jest"
        }
      }
      

Remember, sometimes the simplest way to get your tests running is to mock out parts of the system that aren’t directly related to what you’re testing. If you’re not explicitly testing the behavior of Chart.js, then mocking it might be your best bet.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading