How to write a unit test for angular routing with canActivate guard? I'm getting below error if I use canActivate guard on the routes. If not it is not throwing any error and passing the test. Please help me with a suitable example and also with an explanation.
app-routing.module.ts
export const routes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'home', canActivate: [AuthGuard], component: HomeComponent },
{ path: '**', redirectTo: '/home' }
]
auth-guard.guard.ts
export class AuthGuard implements CanActivate {
private auth: IAuth;
constructor(
private storageService: StorageService,
private router: Router
){}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
this.auth = JSON.parse(this.storageService.getLocalStorageItem('auth'));
if(this.auth){
return true;
}
this.router.navigate(['/'], {queryParams: {returnUrl: state.url}});
return false;
}
}
app-routing.module.test.ts
test(`Navigate to 'home' takes you to /home`, fakeAsync(() => {
router.navigate(['/home']).then(() => {
expect(location.path()).toEqual('/home');
});
flush();
}));
Test Result
Testing Router › Navigate to 'home' takes you to /home
Uncaught (in promise): Error: expect(received).toEqual(expected) // deep equality
Expected: "/home"
Received: "/"
Error: expect(received).toEqual(expected) // deep equality
You should pass true for AuthGuard.canActivate before you run the test. This is a Jasmine example (make the adjustments):
describe('Test Description', () => {
...
beforeEach(() => {
const canActivateStub = () => ({ canActivate: () => true });
... all your imports
TestBed.configureTestingModule({
... (all your imports)
providers: [
{ provide: AuthGuard, useValue: canActivateStub}
]
})
})
...
})
For AuthGuard test unit you can do:
describe('AuthGuard', () => {
let service: AuthGuard;
it('can load instance', () => {
const routerStubInit = () => ({ navigate: (array, object) => ({}) });
TestBed.configureTestingModule({
providers: [
AuthGuard,
HttpClient,
HttpHandler,
{ provide: Router, useFactory: routerStubInit },
]
});
service = TestBed.inject(AuthGuard);
expect(service).toBeTruthy();
});
describe('canActivate', () => {
it('makes expected calls', () => {
const authenticationServiceStub = () => ({ userValue: {} });
const routerStubInit = () => ({ navigate: (array, object) => ({}) });
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
AuthGuard,
HttpClient,
HttpHandler,
{ provide: Router, useFactory: routerStubInit },
{ provide: AuthenticationService, useFactory: authenticationServiceStub }
]
});
service = TestBed.inject(AuthGuard);
const activatedRouteSnapshotStub: ActivatedRouteSnapshot = <any>{};
const routerStateSnapshotStub: RouterStateSnapshot = <any>{};
spyOn(service, 'canActivate').and.callThrough();
service.canActivate(activatedRouteSnapshotStub, routerStateSnapshotStub);
expect(service.canActivate).toHaveBeenCalled();
});
it('makes expected calls', () => {
const routerStubInit = () => ({ navigate: (array, object) => ({}) });
const authenticationServiceStubNull = () => ({ userValue: null });
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
AuthGuard,
HttpClient,
HttpHandler,
{ provide: Router, useFactory: routerStubInit },
{ provide: AuthenticationService, useFactory: authenticationServiceStubNull }
]
});
service = TestBed.inject(AuthGuard);
const routerStub: Router = TestBed.inject(Router);
const activatedRouteSnapshotStub: ActivatedRouteSnapshot = <any>{};
const routerStateSnapshotStub: RouterStateSnapshot = <any>{};
spyOn(routerStub, 'navigate').and.callThrough();
service.canActivate(activatedRouteSnapshotStub, routerStateSnapshotStub);
expect(routerStub.navigate).toHaveBeenCalled();
});
});
});
Any answer to this matter? I got into the same issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.