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() 的方法,但没有成功。
软件版本:
- Angular 10.1.0,
- 茉莉核心 3.6.0,
- 业力 5.2.1
当你进行单元测试时,模拟你注入的所有服务是一件好事,因为你想要 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);
例如。
我需要一些建议如何用一些逻辑测试 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() 的方法,但没有成功。
软件版本:
- Angular 10.1.0,
- 茉莉核心 3.6.0,
- 业力 5.2.1
当你进行单元测试时,模拟你注入的所有服务是一件好事,因为你想要 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);
例如。