我如何测试返回承诺或拒绝的函数 - Jasmine 和 Karma

Posted

技术标签:

【中文标题】我如何测试返回承诺或拒绝的函数 - Jasmine 和 Karma【英文标题】:How can i test a function that return a promise or reject - Jasmine and Karma 【发布时间】:2020-04-07 11:32:18 【问题描述】:

我需要对一个函数进行 100% 的测试,它返回一个 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

【问题讨论】:

【参考方案1】:

在您的测试中,您模拟了被测方法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();
        );
);

有关 Angular 和 Jasmine 的不同测试策略的详细信息,请咨询 https://angular.io/api/core/testing/fakeAsync 和 https://jasmine.github.io/tutorials/async。

【讨论】:

以上是关于我如何测试返回承诺或拒绝的函数 - Jasmine 和 Karma的主要内容,如果未能解决你的问题,请参考以下文章

如何模拟在 AngularJS Jasmine 单元测试中返回承诺的服务?

在 Nodejs 中使用 Jasmine 测试 promise 是不是被解决或拒绝

我如何用 Jasmine 和 Karma 覆盖承诺响应

返回承诺的 Vuex 操作永远不会解析或拒绝

如何在 Mocha 测试中调试“错误:无理由或错误理由拒绝承诺”?

如何保证承诺不会拒绝的API用户