我正在嘗試對我撰寫的服務進行單元測驗。大多數測驗都通過了,但我的最后一個測驗失敗了,盡管我的模擬設定與我的一個作業測驗相同。
這是我的服務。您會注意到我匯入了其他服務來進行 API 呼叫并創建了一個快餐欄。同樣在我的服務中,我有邏輯來確定應該呼叫哪個 API:
showMarkOffline(incident: any): void {
let name;
let apiCall;
if (incident.sessionType === 'network') {
name = incident.networkName;
const nodes = (incident.nodes || []).map((node) => node.id);
apiCall = () => this.hubsApiService.markOffline(incident.id, nodes);
} else {
name = (incident && incident.workerName) ? incident.workerName : incident.id;
const gatewayId = (incident && incident.gatewayId) ? incident.gatewayId : null;
apiCall = this.phonesApiService.markOffLine(gatewayId, incident.id);
}
const dialogRef = this.modalWrapperService.openConfirmDialog('ns.common:markOfflineDialog.title',
['ns.common:markOfflineDialog.content', { 0: name }],
'ns.common:markOfflineDialog.ok',
'ns.common:cancel');
dialogRef.afterClosed().subscribe((confirmation: boolean) => {
if (confirmation) {
apiCall().subscribe(() => {
// the second test doesn't seem to get here
this.snackbarWrapperService
.openSuccess('ns.common:markOfflineDialog.passed', { 0: name });
}, () => {
this.snackbarWrapperService
.openError('ns.common:markOfflineDialog.failed', { 0: name });
});
}
});
}
這很好用,現在我需要撰寫單元測驗:
describe('IncidentsService', () => {
let service: IncidentsService;
const mockHubsApiService = {
markOffline: jest.fn()
};
const mockPhonesApiService = {
markOffLine: jest.fn()
};
const mockModalDialogWrapperService = {
openConfirmDialog: jest.fn()
};
const mockSnackBarWrapperService = {
openSuccess: jest.fn(),
openError: jest.fn()
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{
provide: HubsApiService,
useValue: mockHubsApiService
}, {
provide: PhonesApiService,
useValue: mockPhonesApiService
}, {
provide: ModalDialogWrapperService,
useValue: mockModalDialogWrapperService
}, {
provide: SnackBarWrapperService,
useValue: mockSnackBarWrapperService
}]
});
service = TestBed.inject(IncidentsService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
describe('showMarkOffline', () => {
// this test passes!!!!
it('should call hubsApiService.markOffline, openConfirmDialog and openSuccess', () => {
const incident = {
id: '12345',
sessionType: 'network',
networkName: 'RaduNetwork',
nodes: [{ id: '1', foo: 'bar' }, { id: '2', foo: 'bar' }, { id: '3', foo: 'bar' }, { id: '4', foo: 'bar' }]
};
const modalSpy = spyOn(service.modalWrapperService, 'openConfirmDialog').and
.returnValue({ afterClosed: () => of(true) });
const apiSpy = spyOn(service.hubsApiService, 'markOffline').and
.returnValue(of(true));
const snackBarSpy = spyOn(service.snackbarWrapperService, 'openSuccess');
service.showMarkOffline(incident);
expect(modalSpy).toHaveBeenCalledWith('ns.common:markOfflineDialog.title',
['ns.common:markOfflineDialog.content', { 0: 'RaduNetwork' }],
'ns.common:markOfflineDialog.ok',
'ns.common:cancel');
expect(apiSpy).toHaveBeenCalledWith('12345', ['1', '2', '3', '4']);
expect(snackBarSpy).toHaveBeenCalledWith('ns.common:markOfflineDialog.passed', { 0: 'RaduNetwork' });
});
// this test fails!
it('should call phonesApiService.markOffline, openConfirmDialog and openSuccess',() => {
const incident = {
id: '12345',
workerName: 'workerName',
gatewayId: '54321',
sessionType: 'whatever'
};
const modalSpy = spyOn(service.modalWrapperService, 'openConfirmDialog').and
.returnValue({ afterClosed: () => of(true) });
const apiSpy = spyOn(service.phonesApiService, 'markOffLine').and
.returnValue(of(true));;
const snackBarSpy = spyOn(service.snackbarWrapperService, 'openSuccess');
service.showMarkOffline(incident);
expect(modalSpy).toHaveBeenCalledWith('ns.common:markOfflineDialog.title',
['ns.common:markOfflineDialog.content', { 0: 'workerName' }],
'ns.common:markOfflineDialog.ok',
'ns.common:cancel');
expect(apiSpy).toHaveBeenCalledWith('54321', '12345');
// below is the failing test
expect(snackBarSpy).toHaveBeenCalledWith('ns.common:markOfflineDialog.passed', { 0: 'workerName' });
});
});
});
如您所見,我正在為 API 服務呼叫設定間諜,并且正在為 API 呼叫設定回傳值。問題在于第二個測驗,模擬的服務/間諜確實被呼叫,但該.subscribe方法似乎沒有被執行,因此在第二個測驗中我的代碼永遠不會進入apiCall().subscribe回呼(參見服務中的注釋)和測驗在這里失敗:
expect(snackBarSpy).toHaveBeenCalledWith('ns.common:markOfflineDialog.passed', { 0: 'workerName' });
出現錯誤:
Error: expect(spy).toHaveBeenCalledWith(...expected)
Expected: "ns.common:markOfflineDialog.passed", {"0": "workerName"}
Number of calls: 0
我不確定為什么這適用于第一次測驗而不是第二次。我試過使用ngOnDestroy,我試過改變我的間諜和模擬的設定,但似乎沒有任何東西可以解決第二個單元測驗。
uj5u.com熱心網友回復:
似乎測驗還可以,但實作卻不行。
apiCall = () => this.hubsApiService.markOffline(incident.id, nodes); // passes
vs
apiCall = this.phonesApiService.markOffLine(gatewayId, incident.id); // does not.
我相信這段代碼在運行時也應該失敗,因為在第二種情況下apiCall = someObservable;你不能只打電話給它apiCall()
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/410563.html
標籤:
