Search code examples
angularunit-testingjasminekarma-runner

Angular Jasmine, unit test case fails when global variable assigned


I have a basic unit-test case written for two methods.

 it('should populateChartDatasets call getColorCodes', () => {
    component.chartConfig = mockChartConfig;
    spyOn(component, 'getColorCodes');
    component.populateChartDatasets(filteredTreatments, filteredYears);
    expect(component.getColorCodes).toHaveBeenCalled();
  });

method populateChartDatasets firstly supposed to pick colorCode from method getColorCodes then push prepared dataset to chartConfig.data.datasets.

Everything works pretty good after command ng serve

But this test case fails with the error thrown below

should populateChartDatasets call getColorCodes FAILED
        TypeError: Cannot read properties of undefined (reading '0')

Inside method populateChartDatasets, this line this.chartConfig.data.datasets.push({}) fails because it seems like methods under component.chartConfig = mockChartConfig doesn't wait for this assignment to chartConfig object thats why data.datasets thrown as undefined.

I gave setTimeout 500ms which solved the problem (at least successful but another error in console thrown)

  it('should populateChartDatasets call getColorCodes', () => {
    component.chartConfig = mockChartConfig;
    setTimeout(() => {
      spyOn(component, 'getColorCodes');
      component.populateChartDatasets(filteredTreatments, filteredYears);
      expect(component.getColorCodes).toHaveBeenCalled();
    }, 500);
  });

Spies must be created in a before function or a spec

How can I make this test passed?

Stackblitz example : https://stackblitz.com/edit/unit-test-template-337ysq?file=src/app/app.component.spec.ts


Solution

  • There is only one issue here, so when you are calling "populateChartDatasets" method internally it depends on "getColorCodes" method to return a string. Without this process "populateChartDatasets" method never completes. To fix that you can do like this -

    it('should populateChartDatasets call getColorCodes', () => {
        spyOn(component, 'getColorCodes').and.callFake(d => {
          return "#ffffff"
        });
        component.populateChartDatasets(filteredTreatments, filteredYears);
        expect(component.getColorCodes).toHaveBeenCalled();
    });