How to Test Routing in Angular: Simple Guide with Examples
RouterTestingModule in your test module and use Angular's Router service to simulate navigation. Then, verify the current route or component rendering using Jasmine or Jest assertions.Syntax
Use RouterTestingModule to set up routing in tests. Inject Router and Location to control and check navigation. Use router.navigate() to simulate route changes and fixture.detectChanges() to update the view.
Key parts:
RouterTestingModule.withRoutes(routes): sets up routes for testing.router.navigate(['/path']): simulates navigation.location.path(): gets current URL path.fixture.detectChanges(): refreshes component view after navigation.
import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { Router } from '@angular/router'; import { Location } from '@angular/common'; import { Component } from '@angular/core'; @Component({ template: '<h1>Home</h1>' }) class HomeComponent {} @Component({ template: '<h1>About</h1>' }) class AboutComponent {} const routes = [ { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; describe('Router Test', () => { let router: Router; let location: Location; beforeEach(() => { TestBed.configureTestingModule({ imports: [RouterTestingModule.withRoutes(routes)], declarations: [HomeComponent, AboutComponent] }); router = TestBed.inject(Router); location = TestBed.inject(Location); }); it('should navigate to /home', fakeAsync(() => { router.navigate(['/home']); tick(); expect(location.path()).toBe('/home'); })); });
Example
This example shows how to test navigation between two routes and verify the URL changes correctly.
import { Component } from '@angular/core'; import { TestBed, fakeAsync, tick, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { Router } from '@angular/router'; import { Location } from '@angular/common'; @Component({ template: '<h1>Home</h1>' }) class HomeComponent {} @Component({ template: '<h1>About</h1>' }) class AboutComponent {} @Component({ selector: 'app-root', template: '<router-outlet></router-outlet>' }) class AppComponent {} const routes = [ { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; describe('App Routing', () => { let router: Router; let location: Location; let fixture: ComponentFixture<AppComponent>; beforeEach(() => { TestBed.configureTestingModule({ imports: [RouterTestingModule.withRoutes(routes)], declarations: [AppComponent, HomeComponent, AboutComponent] }); router = TestBed.inject(Router); location = TestBed.inject(Location); fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); }); it('should navigate to /home and display HomeComponent', fakeAsync(() => { router.navigate(['/home']); tick(); fixture.detectChanges(); expect(location.path()).toBe('/home'); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('h1')?.textContent).toContain('Home'); })); it('should navigate to /about and display AboutComponent', fakeAsync(() => { router.navigate(['/about']); tick(); fixture.detectChanges(); expect(location.path()).toBe('/about'); const compiled = fixture.nativeElement as HTMLElement; expect(compiled.querySelector('h1')?.textContent).toContain('About'); })); });
Common Pitfalls
1. Forgetting to call tick() or fakeAsync: Navigation is asynchronous, so tests must wait for it to complete.
2. Not calling fixture.detectChanges() after navigation: This prevents the view from updating to reflect the new route.
3. Missing route declarations in RouterTestingModule.withRoutes(): Without routes, navigation won't work in tests.
4. Testing navigation without injecting Location: You need Location to verify the current URL path.
/* Wrong: Missing tick() and detectChanges() */ it('wrong navigation test', () => { router.navigate(['/home']); expect(location.path()).toBe('/home'); // Fails because navigation is async }); /* Right: Use fakeAsync, tick(), and detectChanges() */ it('correct navigation test', fakeAsync(() => { router.navigate(['/home']); tick(); fixture.detectChanges(); expect(location.path()).toBe('/home'); }));
Quick Reference
- Import
RouterTestingModule.withRoutes(routes)in your test module. - Inject
RouterandLocationto control and check navigation. - Use
router.navigate(['/path'])insidefakeAsynctests withtick(). - Call
fixture.detectChanges()after navigation to update the view. - Verify current URL with
location.path()and check rendered components.