如何对 Resolve 和 CanActivate 进行单元测试

时间:2021-03-12 15:40:35

标签: angular unit-testing angular-routing angular-router-guards

我想对以下守卫进行单元测试

resolve(): Observable < Game > {
  return this.gameRoom$.pipe(
    tap(data => {
      this.gameService.updateGame(data);
    }));
}


canActivate(
  next: ActivatedRouteSnapshot,
  state: RouterStateSnapshot): boolean {
  this.gameRoom$ = this.gameService.fetchGame(next.paramMap.get("gameId")).pipe(shareReplay());
  return this.gameService.isRouteCorrectlyConfigured(state.url);
}

我已经为 CanActivate 设置了以下单元测试

  it("it should not activate route", () => {
    const MockSnapshot = {
      url: ""
    } as RouterStateSnapshot;
    expect(guard.canActivate(route.snapshot, MockRouterStateSnapshot)).toBeFalsy();
  });

  it("it should activate route", () => {
    const MockRouterStateSnapshot = {
      url: "/game/someid/some-place"
    } as RouterStateSnapshot;
    expect(guard.canActivate(route.snapshot, MockRouterStateSnapshot)).toBeTruthy();
  });

但是我如何对解析方法进行单元测试? 我像这样尝试过,但是可观察对象不存在,因为 gameService 没有获取任何东西。测试解析方法是否有意义?我该如何测试?

it("should resolve", () => {
    guard.resolve().subscribe(data => expect(data).toBeTruthy());
  });

1 个答案:

答案 0 :(得分:0)

我发现 resolve() 中没有有意义的流程,所以我不会费心去测试它,但从技术上讲,它绝对是可测试的。

resolve() 没有直接输入(参数),但是它引入了 2 个应该被模拟的间接输入:gameRoom$ 和 gameService。输出是一个实际反映 gameRoom$ 的 observable(返回值),因此您要验证实际 observable 产生的值是否与 gameRoom$-mock 产生的值相同(tap 不会转换源 observable)。

所以这是一个用于实现所需测试的概念示例(未检查编译):


it("should resolve", () => {
  const fakeGame = new Game();
  guard.gameRoom$ = of(fakeGame); // sync-observable
  guard.gameService = { updateGame: (data: any) => ({ }) };
  guard.resolve().subscribe(data => {
    expect(data).toBe(fakeGame);
  });
});
相关问题