简体   繁体   English

尚未调用Jasmine spyOn报告功能

[英]Jasmine spyOn reporting functions have been called when they haven't

I have the following code: 我有以下代码:

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

And the following unit test: 以及以下单元测试:

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

Basically when deleting a job, if the delete was a success with a returned status of 200 then show a success toast and refresh, else show a danger toast. 基本上,在删除作业时,如果删除成功,返回状态为200,则显示成功吐司和刷新,否则显示危险吐司。

I expect the test to fail, as it returns a status of 500, but it passes. 我希望测试失败,因为它返回状态500,但通过了。 This implies that ngToast.success() and scope.refreshApps() have been called. 这意味着已调用ngToast.success()scope.refreshApps()

I added some logs to the code, and it does return status: 500 and go to the else block. 我在代码中添加了一些日志,它确实返回status: 500并转到else块。

What am I missing here? 我在这里想念什么?

The problem is related to the asynchronous nature of deleteJob . 该问题与deleteJob的异步性质有关。 Your it test ends even before expect is performed. 您的it测试甚至在执行expect之前it结束了。 Therefore you need some sort of synchronization. 因此,您需要某种同步。 This could basically be done with fakeAsync and tick from @angular/core/testing . 这基本上可以使用fakeAsync来完成,并从@angular/core/testing tick

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

    sandboxService.deleteJob();
    tick();

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

The problem however is that you're overwriting the original behaviour of deleteJob with the spy below, hence ngToast.success and scope.refreshApps won't be called and the test will fail. 但是问题是,您用下面的间谍程序覆盖了deleteJob的原始行为,因此不会调用ngToast.successscope.refreshApps ,并且测试将失败。

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

@uminder's answer pointed out that the test was finishing before the expect functions were even called due the asynchronous nature - verified by adding some logs inside the test. @uminder的答案指出,由于异步特性,测试甚至在调用expect函数之前就已完成-通过在测试内部添加一些日志来进行验证。

The solution was to add an argument to the test that is to be called when the test has finished: https://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support 解决方案是在测试完成时向测试添加一个参数: 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();
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM