错误:预期对标准“按功能匹配:”的一个匹配请求,未找到。 我搜索了很多东西,并尝试了一些解决方案。但是他们都不起作用。这是我的第一个单元测试项目。这是我的代码。
身份验证拦截器
export class JwtInterceptor implements HttpInterceptor {
constructor(@Inject(API_URL) private apiUrl: string) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({url: this.prepareUrl(request.url)});
let authToken = localStorage.getItem('auth_token');
if (authToken) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`
}
});
}
else {
// use proxy url for cors error
request = request.clone({url: this.prepareUrl('https://cors-anywhere.herokuapp.com/' + request.url)});
// Encode the String
let encodedString = btoa(`${environment.clientId}:${environment.clientSecret}`);
request = request.clone({
setHeaders: {
Authorization: `Basic ${encodedString}`
}
});
}
return next.handle(request);
}
private isAbsoluteUrl(url: string): boolean {
const absolutePattern = /^https?:\/\//i;
return absolutePattern.test(url);
}
private prepareUrl(url: string): string {
url = this.isAbsoluteUrl(url) ? url : this.apiUrl + '/' + url;
return url.replace(/([^:]\/)\/+/g, '$1');
}
}
授权拦截器规范
describe('Jwt Interceptor', ()=> {
let httpTestingController: HttpTestingController;
let http: HttpClient;
beforeEach(()=> {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true
}]
});
httpTestingController = TestBed.get(HttpTestingController);
http = TestBed.get(HttpClient);
});
it('should add Authorization header in each request', ()=> {
http.get('/data').subscribe(response => {
expect(response).toBeTruthy();
});
const req = httpTestingController.expectOne(
req => req.headers.has('Authorization')
);
// expect(req.request.headers.has('Authorization')).toEqual(true);
expect(req.request.method).toEqual('GET');
// req.flush({hello: 'world'});
httpTestingController.verify();
});
afterEach(()=> {
httpTestingController.verify();
});
});
我还尝试通过使用模拟服务设置授权标头。谁能帮我在这里我想念的东西?
答案 0 :(得分:0)
最后,我找到了一个解决方案,这是我进行身份验证拦截器测试的最终代码。使用任何服务方法来发出http请求。因此,它可以正确地验证拦截器。而且,我也忘记了在TestBed配置中提供apiUrl。
import {TestBed} from '@angular/core/testing';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
import {HTTP_INTERCEPTORS, HttpClient} from '@angular/common/http';
import {API_URL, JwtInterceptor} from './jwt.interceptor';
import {DataService} from './data.service';
describe('JwtInterceptor', () => {
let httpClient: HttpClient;
let httpTestingController: HttpTestingController;
let service: DataService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
DataService,
{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true
},
{
provide: API_URL,
useValue: {apiUrl: 'localhost'}
}]
});
httpClient = TestBed.get(HttpClient);
httpTestingController = TestBed.get(HttpTestingController);
service = TestBed.get(DataService);
// for localstorage mocking
let store = {};
const mockLocalStorage = {
getItem: (key: string): string => {
return key in store ? store[key] : null;
},
setItem: (key: string, value: string) => {
store[key] = `${value}`;
},
removeItem: (key: string) => {
delete store[key];
},
clear: () => {
store = {};
}
};
spyOn(localStorage, 'getItem').and.callFake(mockLocalStorage.getItem);
spyOn(localStorage, 'setItem').and.callFake(mockLocalStorage.setItem);
spyOn(localStorage, 'removeItem').and.callFake(mockLocalStorage.removeItem);
spyOn(localStorage, 'clear').and.callFake(mockLocalStorage.clear);
});
afterEach(() => {
httpTestingController.verify();
});
describe('making http calls', () => {
it('adds authorization header', () => {
const apiUrl = TestBed.get(API_URL);
service.getData().subscribe(response => {
expect(response).toBeTruthy();
});
localStorage.setItem('auth_token', 'any auth token here');
const authToken = localStorage.getItem('auth_token');
const req = httpTestingController.expectOne(apiUrl + '/getData');
expect(req.request.headers.has('Authorization')).toEqual(true);
expect(req.request.headers.get('Authorization')).toEqual(`Bearer ${authToken}`);
});
});
});