Angular 10 - 保护单元测试

Angular 10 - Guard unit test

我需要一些建议如何用一些逻辑测试 Guards,因为我有点困惑,如何在 Jasmine/Karma 中使用 mocks/spies:

@Injectable({
    providedIn: 'root'
})
export class RegistrationGuardService implements CanActivate {

    constructor(private credentials: CredentialsService,
                private router: Router) {
    }

    canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
        return this.credentials.getAuthorities().then(() => {
            if (!this.credentials.isGuestOrAdmin()) {
                this.router.navigate(['/sign-in'], {state: {url: routerState.url}});
            }
            return this.credentials.isGuestOrAdmin();
        });
    }
}

这是服务:

export class CredentialsService {
    authenticated: boolean = false;
    authorities: UserRole[];

    constructor(private router: Router,
                private authenticationService: AuthenticationService,
                private authorizationService: AuthorizationService,
                private notificationService: NotificationService) {
        this.getAuthorities().then();
    }

    public async getAuthorities() {
        await this.authorizationService.getAuthorities()
            .pipe(
                map(authorities => authorities.map(element => UserRole.getUserRoleType(element)))
            )
            .toPromise()
            .then(result => {
                this.authorities = result;
                this.authenticated = this.isNotAnonymous();
            })
            .catch(() => {
                this.authorities = [UserRole.ANONYMOUS];
                this.authenticated = this.isNotAnonymous();
            })
    }
}

是否可以模拟服务?我尝试了很多使用 TestBed.inject() 的方法,但没有成功。

软件版本:

当你进行单元测试时,模拟你注入的所有服务是一件好事,因为你想要 unit 测试。服务应该与所有其他组件分开测试。当您模拟服务时,您可以完全控制服务的方法 return.

在您的 TestBed 提供者中,您应该拥有:

providers: [
  {
    provide: CredentialService,
    useValue: {
      getAuthorities: () => /* here what you want the getAuthorities method to return (apparently a promise) */,
      isGuestOrAdmin: () => /* true or false */
  }
]

如果在测试中您需要更改 useValue return 中定义的方法,您可以使用

监视这些属性
spyOn(TestBed.get(CredentialService), 'isGuestOrAdmin').and.returnValue(false);

例如。