How to spyOn a Service method called in the Service constructor
(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();
});
});
Ad: