HttpClient 拦截器重试单元测试(预期没有打开请求,找到 1 个)
HttpClient interceptor retry unit testing (Expected no open requests, found 1)
我有一个简单的 HttpClient 拦截器,它只重试失败的请求一定次数。现在,我正在尝试为其编写单元测试,但不知何故我最终得到了一个未完成的请求。我试过将测试包装在 fakeAsync
中或使用 done
但它似乎没有帮助。现在我没主意了。
我得到的错误是:
Error: Expected no open requests, found 1: GET mock/url
我错过了什么?
server-error.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { retry } from 'rxjs/operators';
import { ConfigService } from '@app/shared/services/config.service';
/**
* Http error interceptor class
*/
@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
constructor(private configService: ConfigService) {}
/**
* Intercepts failed requests and retries set amount of times before throwing an error
*
* @param request HTTP request
* @param next HTTP handler
*
* @returns Observable of Http event
*/
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(retry(this.configService.config.httpRetryCount));
}
}
server-error.interceptor.spec.ts
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ServerErrorInterceptor } from '@core/interceptors/server-error.interceptor';
import { ConfigService } from '@shared/services/config.service';
const mockUrl = 'mock/url';
const mockHttpRetryCount = 5;
const mockErrorText = 'Mock error!';
const mockConfigService: object = {
config: jest.fn().mockReturnValue({
httpRetryCount: mockHttpRetryCount
})
};
describe('ServerErrorInterceptor', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
let interceptor: ServerErrorInterceptor;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
ServerErrorInterceptor,
{ provide: ConfigService, useValue: mockConfigService },
{ provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true }
]
});
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
interceptor = TestBed.get(ServerErrorInterceptor);
});
afterEach(() => {
httpTestingController.verify();
});
it('should be created', () => {
expect(interceptor).toBeTruthy();
});
it('should retry an errored request set amount of times', (): void => {
httpClient.get(mockUrl).subscribe(
null,
(response: HttpErrorResponse): void => {
expect(response.status).toEqual(500);
expect(response.message).toEqual(`Http failure response for ${mockUrl}: 500 Server Error`);
}
);
for (let i = 0; i < mockHttpRetryCount; i += 1) {
const request: TestRequest = httpTestingController.expectOne(mockUrl);
request.flush(mockErrorText, { status: 500, statusText: 'Server Error' });
}
});
});
实际上我自己找到了答案。我的代码中有 3 个独立的错误:
ConfigService
以错误的方式被嘲笑,并为 httpRetryCount
返回 undefined
- 在所有重试失败后拦截器没有抛出错误。
- 应触发测试中的
for
循环 mockHttpRetryCount + 1
以说明所有重试以及最终结果(正或负)
我有一个简单的 HttpClient 拦截器,它只重试失败的请求一定次数。现在,我正在尝试为其编写单元测试,但不知何故我最终得到了一个未完成的请求。我试过将测试包装在 fakeAsync
中或使用 done
但它似乎没有帮助。现在我没主意了。
我得到的错误是:
Error: Expected no open requests, found 1: GET mock/url
我错过了什么?
server-error.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { retry } from 'rxjs/operators';
import { ConfigService } from '@app/shared/services/config.service';
/**
* Http error interceptor class
*/
@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
constructor(private configService: ConfigService) {}
/**
* Intercepts failed requests and retries set amount of times before throwing an error
*
* @param request HTTP request
* @param next HTTP handler
*
* @returns Observable of Http event
*/
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(retry(this.configService.config.httpRetryCount));
}
}
server-error.interceptor.spec.ts
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse } from '@angular/common/http';
import { ServerErrorInterceptor } from '@core/interceptors/server-error.interceptor';
import { ConfigService } from '@shared/services/config.service';
const mockUrl = 'mock/url';
const mockHttpRetryCount = 5;
const mockErrorText = 'Mock error!';
const mockConfigService: object = {
config: jest.fn().mockReturnValue({
httpRetryCount: mockHttpRetryCount
})
};
describe('ServerErrorInterceptor', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
let interceptor: ServerErrorInterceptor;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
ServerErrorInterceptor,
{ provide: ConfigService, useValue: mockConfigService },
{ provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true }
]
});
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
interceptor = TestBed.get(ServerErrorInterceptor);
});
afterEach(() => {
httpTestingController.verify();
});
it('should be created', () => {
expect(interceptor).toBeTruthy();
});
it('should retry an errored request set amount of times', (): void => {
httpClient.get(mockUrl).subscribe(
null,
(response: HttpErrorResponse): void => {
expect(response.status).toEqual(500);
expect(response.message).toEqual(`Http failure response for ${mockUrl}: 500 Server Error`);
}
);
for (let i = 0; i < mockHttpRetryCount; i += 1) {
const request: TestRequest = httpTestingController.expectOne(mockUrl);
request.flush(mockErrorText, { status: 500, statusText: 'Server Error' });
}
});
});
实际上我自己找到了答案。我的代码中有 3 个独立的错误:
ConfigService
以错误的方式被嘲笑,并为httpRetryCount
返回 - 在所有重试失败后拦截器没有抛出错误。
- 应触发测试中的
for
循环mockHttpRetryCount + 1
以说明所有重试以及最终结果(正或负)
undefined