我是Angular测试的新手,正在尝试弄清楚如何编写一个模拟HttpClient.get()函数错误响应的测试。基本上,我的服务在其pipe()中同时具有map()和catchError(),我想同时行使这两种流程。这是我到目前为止的内容:
my.service.ts:
getItems(): Observable<ItemViewModels[]> {
return
this.httpClient.get<any>(this.getItemsUrl)
.pipe(
map(json => {
return json.map(itemJson => this.getVmFromItemJson(itemJson));
}),
catchError(() => {
// Log stuff here...
return of(null);
})
);
}
my.service.spec.ts:
it('should catch error and return null if API returns error', () => {
spyOn(service.httpClient, 'get').and.returnValue(new Observable()); // Mock error here
service.getItems().subscribe($items => expect($items).toBe(null));
});
it('should return valid view model array if API returns a valid json', () => {
const mockResponse = [
new SideNavItemViewModel(1),
new SideNavItemViewModel(2),
new SideNavItemViewModel(3)
];
spyOn(service.httpClient, 'get').and.returnValue(of(JSON.stringify(mockResponse)));
service.getSidenavViewModel().subscribe(x => expect(x).toBe(mockResponse));
});
因此,实际的问题是,我模拟供httpClient返回以在单元测试中返回的可观察对象似乎未进入.pipe()函数,这意味着我的测试无法正常工作:(
有什么想法吗?
谢谢!
答案 0 :(得分:1)
您是否尝试过将服务注入测试?我也尝试测试订阅api调用的功能,而不是创建另一个订阅:
错误:
it('should display error when server error occurs',
inject([HttpTestingController, AService],
(httpMock: HttpTestingController, svc: MyService) => {
svc.getItems(); // has the subscribe in it
const callingURL = svc['API']; // your api call eg. data/items
httpMock.expectOne((req: HttpRequest < any > ) => req.url.indexOf(callingURL) !== -1)
.error(new ErrorEvent('Customer Error', {
error: 500
}), {
status: 500,
statusText: 'Internal Server Error'
});
httpMock.verify();
expect(component.svc.Jobs).toBeUndefined();
fixture.detectChanges();
// UI check here
}));
数据测试
it('should display the correct amount of data elements',
inject([HttpTestingController, AService],
(httpMock: HttpTestingController, svc: MyService) => {
svc.getItems(); // has the subscribe in it
const callingURL = svc['API']; // your api call eg. data/items
const mockReq = httpMock.expectOne((req: HttpRequest < any > ) => req.url.indexOf(callingURL) !== -1);
mockReq.flush(mockData);
httpMock.verify();
expect(component.svc.data.length).toBe(mockData.length);
fixture.detectChanges();
// UI check here
}));
所以基本上这些功能:
我更喜欢这种方式,因为您可以将逻辑和测试分开。