jasmine - тестирование зацикливания при тестировании этого перехватчика - PullRequest
0 голосов
/ 29 августа 2018

У меня есть перехватчик, который автоматически отключает пользователя, если какой-либо ответ содержит 401.

// error.interceptor.ts
import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError} from 'rxjs/operators';
import {AuthService} from 'angularx-social-login';
import {CookieService} from 'ngx-cookie';
import {Router} from '@angular/router';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
  user: any;

  constructor(
    private router: Router,
    private authService: AuthService,
    private cookieService: CookieService
  ) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.user = this.cookieService.getObject('user');

    return next.handle(request).pipe(catchError(err => {
      if (err.status === 401) {
        // auto logout if 401 response returned from api
        this.cookieService.remove('user');
        this.cookieService.remove('google');
        this.authService.signOut();
        location.reload(true);
      }

      const error = err.error.message || err.statusText;
      return throwError(error);
    }));
  }
}

Мой тест на Жасмин выглядит следующим образом. Я высмеял все, кроме перехваченной службы (в данном случае UserService).

// error.interceptor.spec.ts
import { CookieService } from "ngx-cookie";
import { Router } from "@angular/router";
import { AuthService, SocialUser } from "angularx-social-login";
import { UserService } from "../services/user/user.service";
import { TestBed, inject } from "@angular/core/testing";
import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing";
import { HTTP_INTERCEPTORS, HttpClient } from "@angular/common/http";
import { ErrorInterceptor } from "./error.interceptor";
import { environment } from "../../environments/environment";

describe('ErrorInterceptor', () => {
  let cookieServiceMock: jasmine.SpyObj<CookieService>;
  let routerMock: jasmine.SpyObj<Router>;
  let authServiceMock: jasmine.SpyObj<AuthService>
  let service: UserService;

  const cookie = {
    google: {
      'userName': 'john.doe'
    },
    user: {
      'userName': 'john.doe'
    }
  };

  beforeEach(() => {
    routerMock = jasmine.createSpyObj<Router>('Router', ['navigate']);
    authServiceMock = jasmine.createSpyObj<AuthService>('AuthService', ['signOut']);
    cookieServiceMock = jasmine.createSpyObj<CookieService>('CookieService', ['remove', 'putObject', 'getObject']);

    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        {provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true},
        {provide: Router, useValue: routerMock},
        {provide: AuthService, useValue: authServiceMock},
        {provide: CookieService, useValue: cookieServiceMock},
        {provide: SocialUser, useValue: cookie.google},
        UserService
      ]
    })
  });

  afterEach(inject(
    [HttpTestingController],
    (httpMock: HttpTestingController) => {
      httpMock.verify();
    }
  ));

  fit('returns an error if request is invalid',
    inject(
      [HttpClient, HttpTestingController, UserService, HTTP_INTERCEPTORS],
      (http: HttpClient, httpMock: HttpTestingController, service: UserService) => {
          cookieServiceMock.getObject.and.returnValue(cookie.user);

          service.getUserList().subscribe(
            data => console.log(data),
            err => expect(err).toBe('Unauthorized')
          );
          // localhost:8080/v1/api/user
          const req = httpMock.expectOne(environment.coreUrl + environment.basePath + '/user');
          expect(req.request.method).toBe('GET');

          // mocks a response containing a 401 code
          req.flush('Unauthorized', {statusText: 'Unauthorized', status: 401});
      }
    )
  );
});

Обратите внимание, что в приведенном выше тесте используется fit, поэтому при выполнении ng test будет выполняться только этот тест. Когда я запускаю тест, он не заканчивается. Вывод терминала выглядит так:

HeadlessChrome 0.0.0 (Linux 0.0.0): Executed 1 of 182 SUCCESS (0 secs / 0.124 secs)
HeadlessChrome 0.0.0 (Linux 0.0.0): Executed 2 of 182 (skipped 4) SUCCESS (0 secs / 0.161 secs)
HeadlessChrome 0.0.0 (Linux 0.0.0): Executed 3 of 182 (skipped 8) SUCCESS (0 secs / 0.182 secs)
...

Что происходит? И как это можно исправить?

...