Contenido del curso
Fundamentos de unit testing en Angular
Testing en servicios
Proyecto
Testing en consultas HTTP
Bonus
Próximos pasos
Pruebas con interceptores
Contenido del curso
Pruebas con interceptores
Cesar Elías Armendariz Ruano
studentFranco Gavidia
studentAna Velez Ossa
studentJosé Carlos Castro Ramos
studentGerson Pineda
studentPara lograr pruebas con interceptores lo primero sera entender que los interceptores hacen presisamente eso, intereceptar peticiones http y modificarlas o leerlas.
En este caso el interceptor recoge peticiones tipo get de http y les adiciona un token de autorizaciíon en los headers
Las pruebas para verificar que ese token se esta ingresando se pueden ver de la siguiente manera
token.interceptor.ts
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; import { TokenService } from './../services/token.service'; @Injectable() export class TokenInterceptor implements HttpInterceptor { constructor( private tokenService: TokenService ) {} intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { request = this.addToken(request); return next.handle(request); } private addToken(request: HttpRequest<unknown>) { const token = this.tokenService.getToken(); if (token) { const authReq = request.clone({ headers: request.headers.set('Authorization', `Bearer ${token}`) }); return authReq; } return request; } }
token.service.ts
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class TokenService { constructor() { } saveToken(token: string) { localStorage.setItem('token', token); } getToken() { const token = localStorage.getItem('token'); return token; } removeToken() { localStorage.removeItem('token'); } }
app.module.ts
import { TokenInterceptor } from './interceptors/token.interceptor'; @NgModule({ imports: [ ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true } ],
product.service.spec.ts
import { HttpStatusCode, HTTP_INTERCEPTORS } from '@angular/common/http'; import { TokenInterceptor } from '../interceptors/token.interceptor'; import { TokenService } from './token.service'; describe('ProductsService', () => { let productsService: ProductsService; let httpController: HttpTestingController; let tokenService: TokenService; beforeEach(() => { TestBed.configureTestingModule({ imports: [ HttpClientTestingModule ], providers: [ ProductsService, TokenService, { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true } ] }); productsService = TestBed.inject(ProductsService); httpController = TestBed.inject(HttpTestingController); tokenService = TestBed.inject(TokenService); }); describe('tests for getAllSimple', () => { it('should return a product list', (doneFn) => { //Arrange const mockData: Product[] = generateManyProducts(2); spyOn(tokenService, 'getToken').and.returnValue('123'); //Act productsService.getAllSimple() .subscribe((data) => { //Assert expect(data.length).toEqual(mockData.length); expect(data).toEqual(mockData); doneFn(); }); //http config const url = `${environment.API_URL}/api/v1/products`; const req = httpController.expectOne(url); const headers = req.request.headers; expect(headers.get('Authorization')).toEqual(`Bearer 123`); req.flush(mockData); }); });
Tengo una duda, al usar el getToken() del servicio me funciona el test pero yo tenia era un get como propiedad
get loggedIn() { return localStorage.getItem(this._tokenKey); }
//interceptor token = this._authService.loggedIn;
//test spyOn(tokenService, 'loggedIn').and.returnValue('123');
como propiedad da error, como podria hacerlo si uso es una propiedad?
Hola, estoy usando angular 17 y al momento de realizar la prueba el token Interceptor falla. ¿Cuál seria la correcta forma de hacer la prueba con la nueva implementación del los interceptor en angular 17?
Recuerda que a partir de angula 16 ya no usamos HttpClientTestingModule, usamos provideHttpClient().
en este caso tenemos inyección de dependencias para el token.service.ts en token.interceptor.ts entonces es recomendable usar provideHttpClient(withInterceptorsFromDi()), para seguir usando clases. en el archivo de configuración app.config.ts :
providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }, provideHttpClient(withInterceptorsFromDi()), ] ```y en el test:```js TestBed.configureTestingModule({ providers:[ ProductService, TokenService, { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting() ] }); ```TestBed.configureTestingModule({ providers:\[ ProductService, TokenService, { provide: HTTP\_INTERCEPTORS, useClass: TokenInterceptor, multi: true }, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting() ] });
Quiero agregar pruebas al interceptor para la funcion addToken pero como es privada la instancia no me deja accederlo, como podria hacer las pruebas sobre esa funcion?