这是我想要测试的控制器函数。
saveItem = (): void => {
this.updateItem();
this.loadingDialogService.showIndicator("Saving Item");
this._editItemService.updateItem(this.item).then((updatedItem: Item) => {
this.loadingDialogService.cancelDialog();
this.goToMainView();
}).catch(() => {
this.loadingDialogService.showErrorDialog("Failed to Save Item");
//this._log.error("Error CallingItemService");
});
}
这是我的测试:
it("should call method saveItem", () => {
spyOn(controller, 'updateItem');
spyOn(loadingDialogService, 'showIndicator');
spyOn(editItemService, 'updateItem').and.callFake(() => {
let result: Item
deferred.resolve(result);
return deferred.promise;
});
spyOn(loadingDialogService, 'cancelDialog');
spyOn(controller, 'goToMainView');
controller.saveItem();
expect(controller.updateItem).toHaveBeenCalled();
expect(loadingDialogService.showIndicator).toHaveBeenCalled();
expect(_editItemService.updateItem).toHaveBeenCalled();
expect(loadingDialogService.cancelDialog).toHaveBeenCalled();
expect(controller.goToMainView).toHaveBeenCalled();
});
测试在最后两个预期失败,抛出错误说
预期的间谍取消对话框已调用。
预期的间谍goToMainView已被调用。
我猜测试不会执行函数内部的函数。有人能指出错误在哪里吗?
您有一个要解决的承诺,因此您需要在函数调用之后但在测试之前运行摘要循环。
it("should call method saveItem", () => {
spyOn(controller, 'updateItem');
spyOn(loadingDialogService, 'showIndicator');
spyOn(editItemService, 'updateItem').and.callFake(() => {
let result: Item
deferred.resolve(result);
return deferred.promise;
});
spyOn(loadingDialogService, 'cancelDialog');
spyOn(controller, 'goToMainView');
controller.saveItem();
$scope.$digest();
expect(controller.updateItem).toHaveBeenCalled();
expect(loadingDialogService.showIndicator).toHaveBeenCalled();
expect(_editItemService.updateItem).toHaveBeenCalled();
expect(loadingDialogService.cancelDialog).toHaveBeenCalled();
expect(controller.goToMainView).toHaveBeenCalled();
});
话虽如此,您的测试稍后会导致您出现问题,因为它有 5 个断言(expect()s)。当一个失败时,你将不得不浪费时间弄清楚它是哪一个。坚持每个测试一个断言 (OAPT.)这应该是 5 个测试,每个测试有一个断言。这样,当某件事失败时,您就知道它是什么。
解决方案:
在
fakeAsync
内运行测试,并在expect
之前运行tick()
服务:
getFirebaseDoc() {
this.db.firestore.doc('some-doc').get()
.then(this.getFirebaseDocThen)
.catch(this.getFirebaseDocCatch);
}
单元测试:
it('should call getFirebaseDocThen', fakeAsync(() => { // note `fakeAsync`
spyOn(service, 'getFirebaseDocThen');
spyOn(service.db.firestore, 'doc').and.returnValue({
get: (): any => {
return new Promise((resolve: any, reject: any): any => {
return resolve({ exists: true });
});
},
});
service.getFirebaseDoc();
tick(); // note `tick()`
expect(service.getFirebaseDocThen).toHaveBeenCalled();
}));