我如何测试 return 承诺或拒绝的功能 - Jasmine 和 Karma

How can i test a function that return a promise or reject - Jasmine and Karma

我需要覆盖一个函数 100% 的测试,它 returns return new Promise<boolean>((resolve, reject) 这是完整的函数。

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);
            }
        );
    });
}

几天前在这里得到了某人的帮助,我正在尝试根据他的提示解决这个问题,我的测试如下:

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();
}));

这是我目前的报道:

My current coverage

在你的测试中,你mock了被测方法saveData,不会涉及真正的实现,也不会提高代码覆盖率。因此,您应该从测试中删除以下语句。

spyOn(component, 'saveData').and.returnValue(Promise.resolve(true));

您应该模拟方法 legaloneService.saveFinancialData,因为这是一个单元测试。由于 saveData 返回 Promise,您可以使用 done 回调函数。

要获得完整的代码覆盖率,您需要进行以下两个测试。

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.