我有以下代码:
$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,则显示success toast和refresh,否则显示danger toast。
我预计测试会失败,因为它返回的状态是500,但它通过了。这意味着已经调用了ngToast.success()和scope.refreshApps()。
我在代码中添加了一些日志,它确实返回了status: 500并转到了else块。
这里我漏掉了什么?
发布于 2019-08-29 19:05:08
这个问题与deleteJob的异步特性有关。甚至在执行expect之前,您的it测试就结束了。因此,您需要某种类型的同步。这基本上可以通过@angular/core/testing的fakeAsync和tick来完成。
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}));发布于 2019-08-29 20:35:01
@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();
});
});https://stackoverflow.com/questions/57708014
复制相似问题