尚未调用Jasmine spyOn报告功能

时间:2019-08-29 10:17:52

标签: javascript angularjs jasmine karma-jasmine

我有以下代码:

$scope.deleteJob = function(job) {
    SandboxService.deleteJob(job.id).then(res => {
        if (res.status == 200) {
            ngToast.success();
            $scope.refreshApps();
        }
        else {
            ngToast.danger();
        }
    });
};

以及以下单元测试:

it('should show success toast on delete and refresh apps', () => {
    spyOn(sandboxService, 'deleteJob').and.returnValue(Promise.resolve({status: 500}));
    spyOn(ngToast, 'success');
    spyOn(scope, 'refreshApps');

    let mockJob = {
        'id': 1
    };

    scope.deleteJob(mockJob);

    sandboxService.deleteJob().then(() => {
        expect(ngToast.success).toHaveBeenCalled();
        expect(scope.refreshApps).toHaveBeenCalled();
    });
});

基本上,在删除作业时,如果删除成功且返回状态为200,则显示成功吐司和刷新,否则显示危险吐司。

我希望测试失败,因为它返回状态500,但通过了。这意味着ngToast.success()scope.refreshApps()已被调用。

我在代码中添加了一些日志,它确实返回了status: 500并进入了else块。

我在这里想念什么?

2 个答案:

答案 0 :(得分:1)

该问题与deleteJob的异步性质有关。您的it测试甚至在执行expect之前就结束了。因此,您需要某种同步。基本上可以使用fakeAsync中的tick@angular/core/testing来完成。

it('should show success toast on delete and refresh apps', fakeAsync(() => {
    ...

    sandboxService.deleteJob();
    tick();

    expect(ngToast.success).toHaveBeenCalled();
    expect(scope.refreshApps).toHaveBeenCalled();
}));

但是问题是,您用下面的间谍程序覆盖了deleteJob的原始行为,因此将不会调用ngToast.successscope.refreshApps并且测试将失败。

 spyOn(sandboxService, 'deleteJob').and.returnValue(Promise.resolve({status: 500}));

答案 1 :(得分:0)

@uminder的回答指出,由于异步特性,在expect函数被调用之前,测试已经完成-通过在测试内部添加一些日志来验证。

解决方案是在测试完成时向测试添加一个参数:https://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support

it('should show success toast on delete and refresh apps', (done) => {
    spyOn(sandboxService, 'deleteJob').and.returnValue(Promise.resolve({status: 200}));
    spyOn(ngToast, 'success');
    spyOn(scope, 'refreshApps');

    let mockJob = {
        'id': 1
    };

    scope.deleteJob(mockJob);

    sandboxService.deleteJob().then(() => {
        expect(ngToast.success).toHaveBeenCalled();
        expect(scope.refreshApps).toHaveBeenCalled();
        done();
    });
});