我正在尝试在不使用 for 循环的情况下对失败的 httpClient post 请求进行测试
retry
,但我很难找到这样做的示例。大多数解决方案似乎都显示了 for 循环方法。
这是有问题的服务代码和测试。目前这按预期工作,我该如何以 rxjs 可观察功能方式做到这一点?
服务代码:
public getUsers(): Observable<UsersResponse> {
return this.httpClient.post<UsersResponse>(`${usersUrl}/fetchall`, '').pipe(
retry(3),
catchError(() => {
return of({} as UsersResponse)
}),
)
}
测试:
it('getUsers should return an empty value on error', () => {
sub = usersService
.getUsers()
.pipe(
tap((res) => {
expect(res).toEqual({} as UsersResponse)
}),
)
.subscribe()
for (let i = 0, c = retryCount + 1; i < c; i++) {
const req = httpMock.expectOne('/api/fetchall')
req.flush({}, { status: 404, statusText: 'Not Found' })
}
})
这个帖子有答案:如何在 rxjs 中对 retryWhen 运算符进行单元测试?
const sourceObservables = observables => {
let count = 0
return defer(() => observables[count++])
}
const responses = [throwError('oh dear'), of({status: 200})]
const httpMock = {
post: sourceObservables(responses)
}
it('getUsers should return an empty value on error', () => {
sub = usersService
.getUsers()
.pipe(
tap((res) => {
expect(res).toEqual({} as UsersResponse)
}),
)
.subscribe()
})
比您想象的容易。使用
toHaveBeenCalledTimes
。 下面就是一个例子:
describe('getUsers', () => {
beforeEach(() => {
service.getUsers().subscribe();
});
it('should retry 3 times if service returns error', () => {
const getUsersSpy = spyOn(service, 'getUsers').and.returnValue(Observable.throw({status: 404}));
expect(getUsersSpy).toHaveBeenCalledTimes(3)
});
});