问题描述
我需要一个建议,如何使用某种逻辑来测试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()尝试了很多事情,但没有成功。
软件版本:
- 角度10.1.0,
- 茉莉花核心3.6.0,
- 业力5.2.1
解决方法
进行单元测试时,最好对要注入的所有服务进行模拟,以进行 unit 测试。服务应与所有其他组件分开测试。模拟服务时,您可以完全控制服务的方法返回什么。
在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);
例如。