【问题标题】:How to unit test angular guard with observable subscription in constructor如何在构造函数中使用可观察订阅对角度防护进行单元测试
【发布时间】:2019-08-20 15:01:07
【问题描述】:

我正在尝试对一个角度防护装置进行单元测试,该防护装置通过管道传输属于身份验证服务的可观察对象。订阅发生在守卫canActivate() 方法中。

我在可观察的身份验证服务上使用 jasmine 间谍来返回值,但在我的单元测试中从未调用过间谍。

在测试一个组件时,我使用fixture.detectChanges(),但是对于这个守卫,我找不到一种方法来测试它是否根据可观察值返回正确的东西。

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$ 上返回的值不被采用。

当身份验证服务返回的可观察值发生变化时,如何测试守卫返回正确的值?茉莉间谍可以做到吗?

【问题讨论】:

  • 如果我的回答有效,您介意告诉我吗?

标签: angular unit-testing karma-jasmine angular-services


【解决方案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();
});

【讨论】:

    猜你喜欢
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 2019-02-25
    相关资源
    最近更新 更多