[英]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.success
和scope.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.