首页 > 解决方案 > Jasmine spyOn 报告函数在没有被调用时被调用

问题描述

我有以下代码:

$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块。

我在这里想念什么?

标签: javascriptangularjsjasminekarma-jasmine

解决方案


该问题与deleteJob. 您的it测试甚至在expect执行之前就结束了。因此,您需要某种同步。这基本上可以用fakeAsynctickfrom来完成@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.success不会scope.refreshApps被调用,测试也会失败。

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

推荐阅读