我正在尝试测试一个 http 拦截器,但我找不到任何方法。
我不知道为什么 url 不匹配,因为我的 token 记录在控制台中并且请求 url 也是相同的。我在没有拦截器的情况下使用这种方法测试了我所有其他的 http 服务,一切都通过了......
这是拦截器类,代码有效并在每个请求中添加我的不记名 token ,它使用在测试中模拟的 Ionic Platform native 类:
@Injectable()
export class AddHeaderInterceptor implements HttpInterceptor {
public constructor(
private auth: AuthService, private platform: Platform,
private config: ConfigurationService
) {}
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.debug('req', req.url);
return Observable.fromPromise(this.platform.ready())
.switchMap(() => Observable.fromPromise(this.auth.getToken()))
.switchMap((tokens: TokenCacheItem[]) => {
const baseUrl = new RegExp(this.config.getValue('baseUrl'), 'g');
if (! req.url.match(baseUrl)) {
return Observable.of(null);
}
if (tokens.length > 0) {
return Observable.of(tokens[0].accessToken);
}
return Observable.throw(null);
})
.switchMap((token: string) => {
console.debug('token', token);
if (!token || token === null) {
return next.handle(req);
}
const headers = req.headers
.set('Authorization', `Bearer ${token}`)
.append('Content-Type', 'application/json');
const clonedRequest = req.clone({ headers });
return next.handle(clonedRequest);
});
}
}
token 已登录到 karma 控制台,我也检查了 url 并且始终具有良好的 url,但测试失败。
这是我的身份验证服务模拟:
export class AuthServiceMock {
getToken() {
return Promise.resolve([
{ accessToken: 'TEST' }
]);
}
}
平台模拟:
export class PlatformMock {
public ready(): Promise<string> {
return Promise.resolve('READY');
}
}
这是测试:
describe('AddHeaderInterceptor Service', () => {
let http: HttpTestingController;
let httpClient: HttpClient;
let auth: AuthService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
ConfigurationService,
{
provide: HTTP_INTERCEPTORS,
useClass: AddHeaderInterceptor,
multi: true,
},
{ provide: Platform, useClass: PlatformMock },
{ provide: LogService, useClass: LogServiceMock },
{ provide: AuthService, useClass: AuthServiceMock }
],
});
http = TestBed.get(HttpTestingController);
httpClient = TestBed.get(HttpClient);
auth = TestBed.get(AuthService);
});
it('should add Auth header to request', () => {
httpClient.get('/test').subscribe(res => expect(res).toBeTruthy());
const req = http.expectOne({ method: 'GET' });
expect(req.request.url.includes('test')).toBeTruthy();
expect(req.request.headers.has('Authorization')).toBeTruthy();
expect(req.request.headers.get('Authorization')).toEqual('Bearer TEST');
req.flush({
hello: 'world'
});
});
});
我总是遇到同样的错误:
Error: Expected one matching request for criteria "Match method: GET, URL: (any)", found none.
看起来请求从未启动过,我尝试创建一个类实例并直接调用拦截方法,但我已经遇到了同样的错误。
我试图从身份验证服务中窥探 getToken
方法,但它从未被调用过。
所以我不知道为什么会失败。
我尝试用另一个 url 调用另一个服务,但我仍然遇到同样的错误。
我尝试在 http.expectOne('http://localhost:8080/test')
中使用绝对或相对 url,它仍然是一样的:
Expected one matching request for criteria "Match URL: http://localhost:8080/test", found none.
有人有想法吗?
最佳答案
我找到了一个使用 karma done 函数并直接构造 Addheader 对象的解决方案:
fdescribe('AddHeaderInterceptor Service', () => {
let http: HttpTestingController;
let httpClient: HttpClient;
let auth: AuthService;
let logger: LogService;
let config: ConfigurationService;
let platform: Platform;
let interceptor: AddHeaderInterceptor;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
ConfigurationService,
{
provide: HTTP_INTERCEPTORS,
useClass: AddHeaderInterceptor,
multi: true,
},
{ provide: Platform, useClass: PlatformMocked },
{ provide: LogService, useClass: LogServiceMock },
{ provide: AuthService, useClass: AuthServiceMock }
],
});
config = TestBed.get(ConfigurationService);
auth = TestBed.get(AuthService);
logger = TestBed.get(LogService);
platform = TestBed.get(Platform);
httpClient = TestBed.get(HttpClient);
http = TestBed.get(HttpTestingController);
interceptor = new AddHeaderInterceptor(logger, auth, platform, config);
});
fit('should add header to request', (done) => {
expect((interceptor as any) instanceof AddHeaderInterceptor).toBeTruthy();
const next: any = {
handle: (request: HttpRequest<any>) => {
expect(request.headers.has('Authorization')).toBeTruthy();
expect(request.headers.get('Authorization')).toEqual('Bearer TESTO');
return Observable.of({ hello: 'world' });
}
};
const req = new HttpRequest<any>('GET', config.getValue('baseUrl') + 'test');
interceptor.intercept(req, next).subscribe(obj => done());
});
});
关于angular - 无法使用 Karma 和 Jasmine 测试 Angular http 拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51047227/