单元测试角度中的授权标头拦截器不起作用

时间:2019-01-10 13:03:24

标签: javascript angular unit-testing karma-jasmine angular-http-interceptors

错误:预期对标准“按功能匹配:”的一个匹配请求,未找到。 我搜索了很多东西,并尝试了一些解决方案。但是他们都不起作用。这是我的第一个单元测试项目。这是我的代码。

身份验证拦截器

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();
  });    
});

我还尝试通过使用模拟服务设置授权标头。谁能帮我在这里我想念的东西?

1 个答案:

答案 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}`);
  });
 });

});