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

Posted

技术标签:

【中文标题】我如何用 Jasmine 和 Karma 覆盖承诺响应【英文标题】:How can i coverage a promise response with Jasmine and Karma 【发布时间】:2020-04-05 23:33:03 【问题描述】:

我有一个返回和处理承诺的函数,我需要覆盖then 内部的返回,但我不知道该怎么做,我目前正在尝试如下:

    confirmRemoveUser(user: IUser) 
    this.modalService
        .open('Confirma a exclusão do usuário selecionado?', 
            titleText: 'Confirmando exclusão',
            confirmButtonText: 'Sim',
            cancelButtonText: 'Cancelar',
            closeButtonText: 'Fechar',
            buttonType: 'danger'
        )
        .result.then(
            (result: BentoModalConfirmationCloseReason) => 
                if (result === BentoModalConfirmationCloseReason.Confirm) 
                    if (this.removeUser(user)) 
                        this.toastService.open('Usuário excluído com sucesso!',  type: 'success', close: true );
                     else 
                        this.toastService.open('Falha ao excluir o usuário!',  type: 'warning', close: true, duration: 0 );
                    
                
            
        );

我目前正在使用callthrough (),并想象通过一些参数我可以得到承诺,但我不知道如何:

   it('Given_ConfirmRemoveUser_When_UserStepIsCalled_Then_UserIsRemoved', (done) => 

        component.selectedJob = 
        ;

        component.selectedArea = 
        ;

        component.users = [
        ];

        spyOn(modalService, 'open').withArgs('This is modal msg').and.callThrough();

        component.confirmRemoveUser(component.users[0]);

        expect(modalService.open).toHaveBeenCalled();
        done();
    );

我的报道如下图:

Image here!

更新

New Error

【问题讨论】:

【参考方案1】:

你的测试在重写后应该可以工作了:

it('Given_ConfirmRemoveUser_When_UserStepIsCalled_Then_UserIsRemoved', (done) => 
    spyOn(modalService, 'open').and.returnValue(Promise.resolve(BentoModalConfirmationCloseReason.Confirm));
    spyOn(toastService, 'open').and.stub();

    component.confirmRemoveUser(component.users[0])
      .then(r => 
        expect(toastService.open).toHaveBeenCalled();
        done();
      )
      .catch(e => fail(e));
);

您可能还想知道 toast 中将显示什么。因此,宁愿使用expect(toastService.open).toHaveBeenCalledWith(?); 是有意义的。

更新 仅当confirmRemoveUser 将返回Promise 时,上述解决方案才有效。

confirmRemoveUser(user: IUser) 
    return this.modalService
    ...

在您的情况下,使用 done 函数没有意义。您需要使用asyncawait

it('Given_ConfirmRemoveUser_When_UserStepIsCalled_Then_UserIsRemoved', async () => 
    spyOn(modalService, 'open').and.returnValue(Promise.resolve(BentoModalConfirmationCloseReason.Confirm));
    spyOn(toastService, 'open').and.stub();

    await component.confirmRemoveUser(component.users[0]);

    expect(toastService.open).toHaveBeenCalled();
);

fakeAsyncflush 也可以实现同样的效果。

import  fakeAsync, flush  from '@angular/core/testing';
...
it('Given_ConfirmRemoveUser_When_UserStepIsCalled_Then_UserIsRemoved', fakeAsync(() => 
    spyOn(modalService, 'open').and.returnValue(Promise.resolve(BentoModalConfirmationCloseReason.Confirm));
    spyOn(toastService, 'open').and.stub();

    component.confirmRemoveUser(component.users[0]);
    flush();

    expect(toastService.open).toHaveBeenCalled();
));

【讨论】:

看起来不错,但我收到以下错误消息Property 'then' does not exist on type 'void' 我没有注意到confirmRemoveUser 没有返回Promise,请查看更新后的答案。 我尝试了 3 种解决方案,但都有这个错误消息:Cannot read property 'result' of undefined。我认为这就是为什么我没有调用 modalService 所以结果为空,因为我可以调用 modalService.Open 以便它给我一个结果供 toast 使用它? @Guilherme Prado:原因是modalService.open spy 应该返回BentoModalConfirmationCloseReason。我不知道这个classinterface,但会调整我的答案做出猜测。 正在给出问题中更新的错误,但非常感谢您对此提供帮助我可以尝试一些事情,谢谢

以上是关于我如何用 Jasmine 和 Karma 覆盖承诺响应的主要内容,如果未能解决你的问题,请参考以下文章

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

使用 Angular 和 Jasmine/Karma 的私有方法进行测试和代码覆盖

Karma + Browserify + Jasmine + 伊斯坦布尔 + React 覆盖

KarmaJS 中的代码覆盖率过高,具有 karma-coverage 和 Jasmine

使用 karma-jasmine 和 istanbul 的 Typescript 代码覆盖率

使用 karma-jasmine 和 istanbul 的 Typescript 代码覆盖率