I am using Angular 7+.
Summary of the problem :
I have a code inside which there is a setInterval method which calls a url method of a service to retrieve data every 1000 milliseconds. Also note that i do not want my program to first wait for 1000 ms and then call the url method, i.e why i have pre called the method only once before setInterval. Do let me know how to test this exact same behaviour. Also please do not bother much about the implementation as it is done according to business requirement which i cannot disclose.
Problem Statement:
Suppose i have a url to which i check every 1 second whether i am getting data or not. The call to this url is made inside a function getDataFromUrl , inside a service injected into the component.
Please refer the code below.
someStorage = {};
constructor(private service: someService){}
ngOnDestroy(){
clearInterval(this.clearPeriodicRefresh);
}
ngOnChanges(){
let context = this;
this.periodicRefresh(context);
this.clearPeriodicRefresh = setInterval(function(){
this.periodicRefresh(context);
},1000);
}
periodicRefresh(self){
self.service.getDataFromUrl(url).subscribe(res => {
someStorage[res] = true;
},
err =>{
console.log(" Error Occured ");
});
}
Now i am unit testing the code like this:
it('should check for async data from url', fakeAsync()=>{
someServiceStub.getDataFromUrl.and.returnValue(of("chandni chowk"));
fixture.detectChanges();
expect(component.someStorage["chandni chowk"]).toBe(true); // executes successfully
setInterval(()=>{
someServiceStub.getDataFromUrl.and.returnValue(of("delhi"));
},1000);
tick(1000); // in milliseconds
discardPeriodicTasks();
expect(component.someStorage["delhi"]).toBe(true); // throws error
}));
The second expect statement shows :
ERROR : expected undefined to be true
I do not know the reason why . However, if i do a tick(2000) instead of tick(1000), then it works. Again i am not sure why it gets skipped earlier.
NOTE : Any timer between 1000 and 2000 i.e for example till tick(1900) throws the same error, and anytime after 2000 milliseconds works fine.
Also please tell me how to write better tests if there is any other way for this.
setInterval(() => { ... }and there shouldnt be any need for passing any context around, as "this" is component wide context in angular. BTW what are u trying to test here? Your storage? Your service? Your component? regards