Как модульно протестировать angular guard с наблюдаемой подпиской в конструкторе

#angular #unit-testing #karma-jasmine #angular-services

#angular #модульное тестирование #karma-jasmine #angular-services

Вопрос:

Я пытаюсь модульно протестировать angular guard, который передает наблюдаемый объект, принадлежащий службе аутентификации. Подписка выполняется в методе guard canActivate() .

Я использую шпион jasmine в службе аутентификации observable для возврата значений, но шпион никогда не вызывается в моем модульном тестировании.

При тестировании компонента я использую fixture.detectChanges() , но для этого guard я не могу найти способ проверить, что он возвращает правильную вещь в соответствии с наблюдаемым значением.

auth-guard.ts:

 @Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(
    private authService: AuthService,
    private router: Router
  ) {}

  canActivate(): Observable<boolean> {
    return this.authService.isAuthenticated$.pipe(
      map(e => {
        if (e) {
          return true;
        }
      }),
      catchError((err) => {
        this.router.navigate(['/login']);
        return of(false);
      })
    );
  }
}
  

auth.service.ts:

 @Injectable()
export class AuthService {

  private isAuthenticated = new BehaviorSubject<boolean>(false);

  get isAuthenticated$(): Observable<boolean> { return this.isAuthenticated.asObservable(); }

  ...
}
  

auth-guard.spec.ts:

 describe('Authuard', () => {

  let authGuard: AuthGuard;
  let authService: jasmine.SpyObj<AuthService>;

  beforeEach(() => {

    const authServiceSpy = jasmine.createSpyObj('AuthService', ['isAuthenticated$']);

    TestBed.configureTestingModule({
      providers: [
        AuthGuard,
        { provide: AuthService, useValue: authServiceSpy }
      ]
    });

    authGuard = TestBed.get(AuthGuard);
    authService = TestBed.get(AuthService);
  });

  it('should create', () => {
    expect(authGuard).toBeDefined();
  });

  /* This test fails */
  it('should return false when not authenticated', () => {
    authService.isAuthenticated$.and.returnValue(of(false));

    authGuard.canActivate().subscribe(canActivate => {
        expect(canActivate).toBe(false);
    });
  });
});

  

Второй тест завершается неудачей с this.authService.isAuthenticated$.pipe is not a function . Значение, возвращаемое шпионом для IsAuthenticated $, не принимается.

Как я могу проверить, что guard возвращает правильное значение при изменении наблюдаемого значения, возвращаемого службой аутентификации? Возможно ли это сделать с помощью jasmine spies?

Комментарии:

1. Не могли бы вы сообщить мне, сработал ли мой ответ?

Ответ №1:

Попробуйте throwError , как показано ниже:

 import { throwError } from 'rxjs';

it('should return false when not authenticated', () => {
    spyOn(authService,'isAuthenticated$').and.returnValue(throwError('error'));

    authGuard.canActivate().subscribe(canActivate => {
        expect(canActivate).toBeFalsy();
});