0

考虑以下服务示例

export class AuthService {
  private observableCache: { [key: string]: Observable<boolean> } = {};
  private resourceCache: { [key: string]: boolean } = {};

  constructor(private userService: UserService) { }

  isGranted(resource): Observable<boolean> {
    if (this.resourceCache[resource]) {
      return of(this.resourceCache[resource]);
    }

    if (this.observableCache[role]) {
      return this.observableCache[role];
    }

    this.observableCache[resource] = this.userService
        .getCurrentUser()
        .pipe(map((user: User) => user.canAccess(resource)))
        .pipe(share());

    return this.observableCache[resource];
  }
}

在此服务中,我正在检查是否允许用户查看特定资源。

这就是我试图测试它的方式

describe('AuthService', () => {
  let service: AuthService;
  let userService: any;

  beforeEach(() => {
    userService = jasmine.createSpyObj('UserService', ['getCurrentUser']);
    service = new AuthGuardService(userService);
  });

  describe('isGranted', () => {
    const user: User = {id: 123};

    beforeEach(() => {
      userService.getCurrentUser.and.returnValue(
        hot('-^u', { u: user })
      );
    });

    it('should prove response being cached', () => {
      service.isGranted('dashboard').subscribe();
      service.isGranted('dashboard').subscribe();

      expect(userService.getCurrentUser).toHaveBeenCalledTimes(1);
    });
  });
});

测试的目的是检查资源缓存是否有效。但我注意到的是,如果我替换以下代码段

  service.isGranted('dashboard').subscribe();
  service.isGranted('dashboard').subscribe();

用简单

  service.isGranted('dashboard');
  service.isGranted('dashboard');

测试仍然有效,我是 RxJS 和大理石测试的新手,但据我所知,Observable 在订阅之前不应该工作。

问题 - 为什么它是双向的?

4

1 回答 1

1

测试使用的代码是异步的,尝试使用fakeAsync和运行它tick

it('should prove response being cached', fakeAsync(() => {
  service.isGranted('dashboard').subscribe();
  service.isGranted('dashboard').subscribe();
  tick();
  expect(userService.getCurrentUser).toHaveBeenCalledTimes(1);
}));

查看https://angular.io/guide/testing#component-with-async-service了解更多信息。

于 2019-07-29T11:10:45.023 回答