I have been struggling to resolve a problem with Angular 9, Jasmine, and RxJS without much success. While my unit tests run successfully in Jasmine, there are certain lines of code that do not get executed.
Despite scouring multiple posts for assistance, none of the solutions provided seem to work for my specific issue, leaving me quite frustrated.
I am reaching out for help, please :)
CLASS TEST
describe('AuthRefreshAppInterceptor', () => {
let accessToken: string;
let endpoint: string;
let authAppServiceMock: AuthAppService;
let baseHTTPService: BaseHTTPService;
let environmentServiceMock: EnvironmentService;
let httpTestingController: HttpTestingController;
let sessionStorageServiceMock: SessionStorageService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
CriptografiaService,
BaseHTTPService,
{
provide: AuthAppService,
useValue: jasmine.createSpyObj('AuthAppService', ['getNewAuth', 'saveAuth', 'createBodyAuth', 'createBodyAuth'])
},
{
provide: EnvironmentService,
useValue: EnvironmentMock
},
{
provide: HTTP_INTERCEPTORS,
useClass: AutorizacaoErroAppInterceptor,
multi: true,
},
{
provide: SessionStorageService,
useValue: jasmine.createSpyObj('SessionStorageService', ['saveItem', 'getItem', 'removeItem'])
}
],
});
authAppServiceMock = TestBed.inject(AuthAppService);
baseHTTPService = TestBed.inject(BaseHTTPService);
environmentServiceMock = TestBed.inject(EnvironmentService);
httpTestingController = TestBed.inject(HttpTestingController);
sessionStorageServiceMock = TestBed.inject(SessionStorageService);
accessToken = faker.finance.bitcoinAddress();
endpoint = faker.internet.domainName();
sessionStorageServiceMock.getItem = jasmine.createSpy()
.and.returnValue({ access_token: accessToken });
});
afterEach(() => {
httpTestingController.verify();
authAppServiceMock.obterAutorizacaoApp = jasmine.createSpy()
.and.returnValue(Observable.of({
access_token: 'eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5oMXY4YlZsODg2M3g3UnhWTlJhamciLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1OTE3OTU5MjAsImV4cCI6MTU5MTc5OTUyRJhdnjh78sjiHDhdiajsd9sb2NhbGhvc3Q6NTUwMDEiLCJhdWQiOiJJZGVudGl0eVNlcnZlckFwaSIsImNsaWVudF9pZCI6IkFkbWluIiwic2NvcGUiOlsiSWRlbnR86d5F4dasdf.Gvxq02a2HaF4rpeB3KnBxRAHHa6WpU850V5377wpRBAA6rmw6PRzVRMnpd2mtr5CVY72NWCspsdU8a8XhwFTgoCDmjSlXKSZKmUGsEaCbXuzSQg7BwD7A9zul0U0VkbF1KTvLIdnmb1noyeOP04dDH',
expires_in: 3600,
token_type: 'Bearer',
scope: 'IdentityServerApi'
}));
});
it('Should execute a request GET and return a HttpErrorResponse with error 401 Unauthorized', () => {
spyOn(baseHTTPService, 'httpGet').and.callThrough();
baseHTTPService.httpGet(endpoint).subscribe({
error: (httpErrorResponse: HttpErrorResponse) => {
console.log(httpErrorResponse)
expect(httpErrorResponse.status).toEqual(401);
expect(httpErrorResponse.statusText).toEqual('Unauthorized');
expect(httpErrorResponse.message).toContain('Http failure response for');
}
});
const httpRequest = httpTestingController.expectOne(
`${environmentServiceMock.apiGatewayURL}/${endpoint}`
);
httpRequest.flush(null, { status: 401, statusText: 'Unauthorized' });
expect(baseHTTPService.httpGet).toHaveBeenCalledTimes(1);
expect(httpRequest.request.url).toBe(`${environmentServiceMock.apiGatewayURL}/${endpoint}`);
expect(httpRequest.request.method).toBe('GET');
expect(httpRequest.request.body).toBeNull();
});
...
});
INTERCEPTOR: TESTED CLASS
export class AuthRefreshAppInterceptor {
...
private getNewAuth(request: HttpRequest<any>, next: HttpHandler) {
return this.authAppService
.getAuthApp()
.pipe(
// THIS BLOCK IS NOT TESTED
switchMap((auth: AuthAppModel) => {
this.authAppService.saveAuth(auth);
return next.handle(this.addHeaders(request));
}),
// THIS BLOCK IS NOT TESTED
catchError(() => next.handle(request))
);
}
...
}
SERVICE
export class AuthAppService {
...
public salvarAutorizacao(auth: AuthAppModel) {
this.sessionStorageService.removeItem(this.authKey);
this.sessionStorageService.saveItem(this.authKey, auth);
}
public getAuthApp(): Observable<AuthAppModel> {
return this.httpClient.post<AuthAppModel>(
`${this.environmentService.apiGateway}/identity/token`,
this.createBodyAuth(),
{ headers: this.createHeaders() }
);
}
...
}
Thank's