使用 retry() 和 HttpClientTestingModule 测试 HTTP 请求
Testing an HTTP request with retry() and HttpClientTestingModule
我想用 HttpClientTestingModule
测试 HTTP 调用错误响应。这工作正常,直到我将 rxjs retry(2)
添加到 HTTP 调用。然后,测试明显报错说发现了一个意外的请求:
Expected no open requests, found 1
但是现在,我不知道如何使用 HttpTestingController
:
来期待两个请求
service.ts
@Injectable()
export class Service {
constructor(private http: HttpClient) { }
get() {
return this.http.get<any>('URL')
.pipe(
retry(2),
catchError(error => of(null))
)
}
}
service.spec.ts
describe('Service', () => {
let httpTestingController: HttpTestingController;
let service: Service;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Service],
imports: [HttpClientTestingModule]
});
httpTestingController = TestBed.get(HttpTestingController);
service = TestBed.get(Service);
});
afterEach(() => {
httpTestingController.verify();
});
it('should handle 404 with retry', () => {
service.get().subscribe((data: any) => {
expect(data).toBe(null);
});
expectErrorResponse(404);
});
function expectErrorResponse(status: number) {
const requests = httpTestingController.match('URL');
// fails -> finds only one request
expect(requests.length).toBe(2);
requests.forEach(req => req.flush('error', {status, statusText: 'Not Found'}));
}
});
如果我删除 expect(requests.length).toBe(2)
,测试将失败并显示之前的错误消息。
运行 例子
你可以试试这个Stackblitz
The fundamentals of Angular - HttpClient - retry() 状态:
The RxJS library offers several retry operators that are worth
exploring. The simplest is called retry() and it automatically
re-subscribes to a failed Observable a specified number of times.
Re-subscribing to the result of an HttpClient method call has the
effect of reissuing the HTTP request.
所以每次调用 flush 时它都会留下一个打开的请求。您只需要在服务重试请求时重复请求处理和刷新次数。
it('can test for 404 error', () => {
const emsg = 'deliberate 404 error';
testService.getData().subscribe(
data => fail('should have failed with the 404 error'),
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404, 'status');
expect(error.error).toEqual(emsg, 'message');
}
);
const retryCount = 3;
for (var i = 0, c = retryCount + 1; i < c; i++) {
let req = httpTestingController.expectOne(testUrl);
req.flush(emsg, { status: 404, statusText: 'Not Found' });
}
});
我想用 HttpClientTestingModule
测试 HTTP 调用错误响应。这工作正常,直到我将 rxjs retry(2)
添加到 HTTP 调用。然后,测试明显报错说发现了一个意外的请求:
Expected no open requests, found 1
但是现在,我不知道如何使用 HttpTestingController
:
service.ts
@Injectable()
export class Service {
constructor(private http: HttpClient) { }
get() {
return this.http.get<any>('URL')
.pipe(
retry(2),
catchError(error => of(null))
)
}
}
service.spec.ts
describe('Service', () => {
let httpTestingController: HttpTestingController;
let service: Service;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [Service],
imports: [HttpClientTestingModule]
});
httpTestingController = TestBed.get(HttpTestingController);
service = TestBed.get(Service);
});
afterEach(() => {
httpTestingController.verify();
});
it('should handle 404 with retry', () => {
service.get().subscribe((data: any) => {
expect(data).toBe(null);
});
expectErrorResponse(404);
});
function expectErrorResponse(status: number) {
const requests = httpTestingController.match('URL');
// fails -> finds only one request
expect(requests.length).toBe(2);
requests.forEach(req => req.flush('error', {status, statusText: 'Not Found'}));
}
});
如果我删除 expect(requests.length).toBe(2)
,测试将失败并显示之前的错误消息。
运行 例子
你可以试试这个Stackblitz
The fundamentals of Angular - HttpClient - retry() 状态:
The RxJS library offers several retry operators that are worth exploring. The simplest is called retry() and it automatically re-subscribes to a failed Observable a specified number of times. Re-subscribing to the result of an HttpClient method call has the effect of reissuing the HTTP request.
所以每次调用 flush 时它都会留下一个打开的请求。您只需要在服务重试请求时重复请求处理和刷新次数。
it('can test for 404 error', () => {
const emsg = 'deliberate 404 error';
testService.getData().subscribe(
data => fail('should have failed with the 404 error'),
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404, 'status');
expect(error.error).toEqual(emsg, 'message');
}
);
const retryCount = 3;
for (var i = 0, c = retryCount + 1; i < c; i++) {
let req = httpTestingController.expectOne(testUrl);
req.flush(emsg, { status: 404, statusText: 'Not Found' });
}
});