【问题标题】:Angular 10 - Guard unit testAngular 10 - 保护单元测试
【发布时间】:2020-09-10 07:28:34
【问题描述】:

我需要一个建议如何用一些逻辑来测试 Guards,因为我有点困惑,如何在 Jasmine/Karma 中使用模拟/间谍:

@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() 的方法,但没有成功。

软件版本:

  • Angular 10.1.0,
  • Jasmine Core 3.6.0,
  • 业力 5.2.1

【问题讨论】:

  • 你读过 Angular 的测试文档吗?它们涵盖了很多不同的情况,包括注入测试替身:angular.io/guide/testing。如果您有具体问题,请给minimal reproducible example 提供比“没有成功” 更好的问题描述。
  • 是的,我读过,但问题是我有 canActivate 方法主体的特定案例
  • 然后给出该特定问题的 MRE。

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


【解决方案1】:

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

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

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

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

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

例如。

【讨论】:

  • 非常感谢!那是解决方案!
猜你喜欢
  • 2012-11-05
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 2015-08-23
  • 2020-08-08
  • 2017-04-04
  • 2019-03-24
  • 2016-12-29
相关资源
最近更新 更多