How to spyOn a Service method called in the Service constructor

/ October 7, 2018/ Karma/Jasmine, Unit Tests

(Last Updated On: November 27, 2018)

I have this service called StatisticsProvider that calls their public method getGeneralStats() in the constructor as first run initialization.

Ad:

StatisticsProvider

import { Injectable  } from '@angular/core';

@Injectable()
export class StatisticsProvider {
    
    constructor() {
        console.log('Hello StatisticsProvider Provider');
        this.getGeneralStats();
    }

    getGeneralStats() {
        console.log("getGeneralStats() needs to be spy on!");
    }
}

Testing it was a problem because I could not spyOn the method before the class was instantiated and of course after that it was too late!

The solution to the question how to test a service constructor with Jasmine in an Angular App was to understand (again) That Typescript is a superset of Javascript, lets take a look at the generated Javascript code of my Service class (without the imports, export and decorator):

var StatisticsProvider = /** @class */ (function () {
    function StatisticsProvider() {
        console.log('Hello StatisticsProvider Provider');
        this.getGeneralStats();
    }
    StatisticsProvider.prototype.getGeneralStats = function () {
        console.log("getGeneralStats()");
    };
    return StatisticsProvider;
}());
Ad:

The trick here is that we can set a spyOn at any function in the prototype and it will be watched when the constructor is called.

Spect File

import { StatisticsProvider } from "./statistics.service";

describe("StatisticsProvider", () => {
    let statisticsProvider: StatisticsProvider;

    it("should call #getGeneralStats in the constructor", () => {
        let getGeneralStats_Spy = spyOn(StatisticsProvider.prototype, 'getGeneralStats');
    
        statisticsProvider = new StatisticsProvider();

        expect(getGeneralStats_Spy).toHaveBeenCalled();
    });

});
… I’ll be watching you 🎵
Ad:
Spread the love

Leave a Reply

avatar
  Subscribe  
Notify of