I need to cover 100% of the tests of a function, it returns a return new Promise<boolean>((resolve, reject)
this is the full function.
saveData(): Promise < boolean > {
return new Promise < boolean > ((resolve, reject) => {
this.legaloneService.saveFinancialData(this.financialModel).subscribe(
m => {
if (!m.Success) {
const mapFiels: {
[id: string]: string
} = {};
mapFiels['accountName'] = 'Nome da conta';
mapFiels['bankId'] = 'Banco';
mapFiels['agency'] = 'Agência';
mapFiels['accountNumber'] = 'Conta';
this.functionsService.displayErrorFromAPII(m, mapFiels);
}
resolve(m.Success);
},
error => {
const msg = 'Ocorreu uma falha ao salvar os dados financeiros';
this.functionsService.cathError(error, msg);
reject(msg);
}
);
});
}
A few days ago I got help from someone here, and I am trying to solve this issue using his tips, my test is as follows:
it('testing resolve a promise', fakeAsync(() => {
spyOn(component, 'saveData').and.returnValue(Promise.resolve(true));
spyOn(funcService, 'displayErrorFromAPII').and.stub();
component.saveData()
.then(r => {
console.log(r);
expect(funcService.displayErrorFromAPII).toHaveBeenCalled();
flush(200);
})
.catch(e => fail(e));
expect(component.saveData).toHaveBeenCalled();
}));
and this is my current coverage:
In your test, you mocks the method saveData
under test, the real implementation will not be involved and code coverage will not improve. Therefore you should remove the following statement from your test.
spyOn(component, 'saveData').and.returnValue(Promise.resolve(true));
You should mock the method legaloneService.saveFinancialData
instead since this is a unit test. Since saveData
is returning a Promise
, you can use the done
callback function.
To have full code coverage, you need the following two tests.
import { of, throwError } from 'rxjs';
...
it('#saveData should display error when financial data cannot be saved', (done) => {
const saveFinancialDataResult = ?; // replace ? with expected !Success result
spyOn(legaloneService, 'saveFinancialData').and.returnValue(of(saveFinancialDataResult));
spyOn(funcService, 'displayErrorFromAPII').and.stub();
component.saveData()
.then(r => {
expect(funcService.displayErrorFromAPII).toHaveBeenCalled();
done();
})
.catch(e => fail(e));
});
it('#saveData should catch error when error occurs', (done) => {
spyOn(legaloneService, 'saveFinancialData').and.returnValue(throwError('server error'));
spyOn(funcService, 'cathError').and.stub();
component.saveData()
.then(r => fail('should have been rejected'))
.catch(e => {
expect(functionsService.cathError).toHaveBeenCalled();
done();
});
});
Please consult https://angular.io/api/core/testing/fakeAsync and https://jasmine.github.io/tutorials/async for detailed information about different testing strategies with Angular and Jasmine.