Я написал угловой тест для проверки кода httpstatus 0, возвращаемого, когда служба недоступна. Во время выполнения теста я получаю следующую ошибку. Какова возможная проблема здесь
Testing the interceptor class > making http calls > Adds a deliberate error code 0
Error: Expected undefined to equal 0.
Expected undefined to equal 'deliberate 0 error - Unknown Error'.
Error: Expected undefined to equal 'deliberate 0 error - Unknown Error'.
Обновление: я обновил код модульного теста, который включает определение класса перехватчика, который может помочь с диагностикой проблемы
Модульный тест
import { TestBed, inject } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse } from '@angular/common/http';
import { HttpWebInterceptor } from './httpWebInterceptor.service';
import { RouterTestingModule } from '@angular/router/testing';
import { OfflineComponent } from '../components/offline/offline.component';
import { Router } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { Observable } from 'rxjs';
import { AlertService } from './alert.service';
class MockUser {
clientCompanyId: number;
}
class MockAuthService {
get currentUser() : MockUser {
let user = {clientCompanyId : 4};
return user;
}
}
class MockAlertService {
resetStickyMessage() {
}
}
describe('Testing the interceptor class', function () {
let httpWebInterceptor: HttpWebInterceptor;
let httpMock: HttpTestingController;
let httpClient: HttpClient;
let routerSpy = { navigate: jasmine.createSpy('navigate') };
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
OfflineComponent
],
imports: [HttpClientTestingModule,
RouterTestingModule.withRoutes([
{ path: 'offline', component: OfflineComponent }
])
],
providers: [HttpWebInterceptor,
{ provide: AlertService, useClass: MockAlertService },
{ provide: AuthService, useClass: MockAuthService },
{ provide: HTTP_INTERCEPTORS, useClass: HttpWebInterceptor, multi: true },
{ provide: Router, useValue: routerSpy }
],
});
httpMock = TestBed.get(HttpTestingController);
httpClient = TestBed.get(HttpClient);
httpWebInterceptor = TestBed.get(HttpWebInterceptor);
});
describe('making http calls', () => {
it('Adds a deliberate error code 0', inject([HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
spyOn(console, 'error');
const fakeUrl = "http://localhost:57973/";
const mockErrorResponse = { status: 0, statusText: 'deliberate 0 error - Unknown Error' };
const emsg = 'deliberate 0 error - Unknown Error';
let errResponse: any;
http.get(fakeUrl).subscribe(
(response) => {
fail('deliberate 0 error - Unknown Error');
},
(error: HttpErrorResponse) => {
expect(error.status).toEqual(0, 'status');
expect(error.error).toEqual(emsg, 'message');
});
const req = httpMock.expectOne(fakeUrl);
httpMock.verify();
req.flush(emsg, { status: 0, statusText: 'Unknown Error' });
expect(routerSpy.navigate).toHaveBeenCalledWith(['offline']);
expect(console.error).toHaveBeenCalled();
}));
});
describe('making http calls', () => {
it('Adds a deliberate error code 404', inject([HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => {
spyOn(console, 'error');
const fakeUrl = "http://localhost:57973/";
const emsg = 'deliberate 404 error - Not Found';
http.get(fakeUrl).subscribe(
(response) => {
fail('should have failed with the 404 error');
},
(error: HttpErrorResponse) => {
expect(error.status).toEqual(404, 'status');
expect(error.error).toEqual(emsg, 'message');
});
const req = httpMock.expectOne(fakeUrl);
req.flush(emsg, { status: 404, statusText: 'Not Found' });
// toHaveBeenCalledWith() looks at all the spy's calls. Use instead toEqual()
expect(routerSpy.navigate).not.toEqual(['offline']);
expect(console.error).toHaveBeenCalled();
}));
});
});
Обновление 2: класс перехватчика
import { Injectable, isDevMode } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpResponse,
HttpHandler,
HttpEvent,
HttpErrorResponse
} from '@angular/common/http';
import { AuthService } from "../services/auth.service";
import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
import { HttpStatusCode } from '../services/system-constants';
import { AlertService, MessageSeverity } from '../services/alert.service';
@Injectable()
export class HttpWebInterceptor implements HttpInterceptor {
constructor(public router: Router,
private authService: AuthService,
private alertService: AlertService
) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!request.headers.has('Content-Type')) {
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
}
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('event', event);
if(event.status == HttpStatusCode.OK)
{
if (this.router.url == '/offline') {
// Website is back online
console.log('redirecting to login');
this.authService.gotoLoginPage();
}
}
}
return event;
}),
catchError((error: HttpErrorResponse) => {
if (error.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
if(isDevMode()) console.error('An error occurred:', error.error.message);
}
else
{
if(isDevMode())
console.error('Backend returned code ${error.status}, body was: ${error.error}');
switch(error.status)
{
case HttpStatusCode.Unknown:
{
if (this.router.url != '/offline')
{
this.authService.clearUserData();
this.alertService.resetStickyMessage();
this.alertService.showMessage("No Network", "The server cannot be reached", MessageSeverity.error);
this.router.navigate(['offline']);
break;
}
}
default:
break;
}
}
return throwError(error);
}));
}
}
Обновление 3: классы имитации
class MockAuthService {
get currentUser() : MockUser {
let user = {clientCompanyId : 4};
return user;
}
clearUserData() {
}
}
class MockAlertService {
resetStickyMessage() {
}
showMessage() {
}
}