Search code examples
angularunit-testingjasminespy

Angular unit test spyOn not detecting my call


I've got a problem with a unit test I can't solve. Here is my test :

fit('should call the alert service in case something went wrong getting the list of files', async(() => {
     spyOn(this.component.alert, 'error');
     this.component.onInputChange('error');
     this.fixture.whenStable().then((() => {
         expect(this.component.alert.error).toHaveBeenCalledWith('an error occured');
     }));
}));

And here is the part of the component I'm testing :

private onInputChange (search: string) {
    const that = this;
    this.translateFileService.getVideoFiles(search)
        .then(files => (files.length) ? this.files = files : '')
        .catch(this.alert.error.bind(that));
}

For testing purpose, the translateFileService is mocked like this :

class TranslateFileServiceMock {

    getVideoFiles (search: string): Promise<IcoFile[]> {
        const fileList = [
            IcoFile.fromJSON({id: '0', label: 'test0', creationTime: '2017-07-01'}),
            IcoFile.fromJSON({id: '1', label: 'test1', creationTime: '2017-07-02'}),
            IcoFile.fromJSON({id: '2', label: 'test2', creationTime: '2017-07-03'}),
        ];

        return new Promise<IcoFile[]>((resolve, reject) => {
            if (search === 'error') return reject('an error occured');
            return resolve(fileList.filter(f => f.label.includes(search)));
        });
    }

}

The onInputChange method call the alert service representated by the alert property in my component. The alert service is not mocked, it is the real service. The call to it's error method is actually made, I already verified. But my test is always failing : the spy is not detecting my call.

I always got the following error :

Expected spy error to have been called with [ 'an error occured' ] but it was never called.

I don't know what to do. I tried everything I know about. At first I thought my call was not properly detected because I was mocking my alert service, but even with the real one it's not working.

I hope you can help, thanks in advance !


Solution

  • Seems this.fixture.whenStable().then is executed before catch handler. I would use fakeAsync with tick

    fit('should call ...', fakeAsync(() => {
      spyOn(component.alert, 'error');
      component.onInputChange('error');
      tick();
      expect(component.alert.error).toHaveBeenCalledWith('an error occured');
    }));
    

    Plunker Example