d48cda4081
CI / Test (ubuntu-latest, Node 18.x, bun) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, npm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, pnpm) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 18.x, yarn) (push) Failing after 15m1s
CI / Test (ubuntu-latest, Node 20.x, bun) (push) Failing after 17m13s
CI / Test (ubuntu-latest, Node 20.x, npm) (push) Failing after 18m42s
CI / Test (ubuntu-latest, Node 20.x, pnpm) (push) Failing after 15m0s
CI / Test (ubuntu-latest, Node 20.x, yarn) (push) Failing after 49m44s
CI / Test (ubuntu-latest, Node 22.x, bun) (push) Failing after 51m55s
CI / Test (ubuntu-latest, Node 22.x, pnpm) (push) Failing after 21m57s
CI / Test (ubuntu-latest, Node 22.x, npm) (push) Failing after 37m39s
CI / Test (ubuntu-latest, Node 22.x, yarn) (push) Failing after 34m7s
CI / Validate Components (push) Failing after 37m15s
CI / Python Tests (push) Failing after 10m1s
CI / Security Scan (push) Failing after 10m1s
CI / Lint (push) Failing after 17m12s
CI / Coverage (push) Failing after 20m19s
CI / Test (macos-latest, Node 18.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 18.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 20.x, yarn) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, bun) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (macos-latest, Node 22.x, yarn) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, npm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, pnpm) (push) Has been cancelled
CI / Test (windows-latest, Node 22.x, yarn) (push) Has been cancelled
3.8 KiB
3.8 KiB
Testing with the RouterTestingHarness
When testing components that involve routing, it is crucial not to mock the Router or related services. Instead, use the RouterTestingHarness, which provides a robust and reliable way to test routing logic in an environment that closely mirrors a real application.
Using the harness ensures you are testing the actual router configuration, guards, and resolvers, leading to more meaningful tests.
Setting Up for Router Testing
The RouterTestingHarness is the primary tool for testing routing scenarios. You also need to provide your test routes using the provideRouter function in your TestBed configuration.
Example Setup
import {TestBed} from '@angular/core/testing';
import {provideRouter} from '@angular/router';
import {RouterTestingHarness} from '@angular/router/testing';
import {Dashboard} from './dashboard.component';
import {HeroDetail} from './hero-detail.component';
describe('Dashboard Component Routing', () => {
let harness: RouterTestingHarness;
beforeEach(async () => {
// 1. Configure TestBed with test routes
await TestBed.configureTestingModule({
providers: [
// Use provideRouter with your test-specific routes
provideRouter([
{path: '', component: Dashboard},
{path: 'heroes/:id', component: HeroDetail},
]),
],
}).compileComponents();
// 2. Create the RouterTestingHarness
harness = await RouterTestingHarness.create();
});
});
Key Concepts
provideRouter([...]): Provide a test-specific routing configuration. This should include the routes necessary for the component-under-test to function correctly.RouterTestingHarness.create(): Asynchronously creates and initializes the harness and performs an initial navigation to the root URL (/).
Writing Router Tests
Once the harness is created, you can use it to drive navigation and make assertions on the state of the router and the activated components.
Example: Testing Navigation
it('should navigate to a hero detail when a hero is selected', async () => {
// 1. Navigate to the initial component and get its instance
const dashboard = await harness.navigateByUrl('/', Dashboard);
// Suppose the dashboard has a method to select a hero
const heroToSelect = {id: 42, name: 'Test Hero'};
dashboard.selectHero(heroToSelect);
// Wait for stability after the action that triggers navigation
await harness.fixture.whenStable();
// 2. Assert on the URL
expect(harness.router.url).toEqual('/heroes/42');
// 3. Get the activated component after navigation
const heroDetail = await harness.getHarness(HeroDetail);
// 4. Assert on the state of the new component
expect(await heroDetail.componentInstance.hero.name).toBe('Test Hero');
});
it('should get the activated component directly', async () => {
// Navigate and get the component instance in one step
const dashboardInstance = await harness.navigateByUrl('/', Dashboard);
expect(dashboardInstance).toBeInstanceOf(Dashboard);
});
Best Practices
- Navigate with the Harness: Always use
harness.navigateByUrl()to simulate navigation. This method returns a promise that resolves with the instance of the activated component. - Access the Router State: Use
harness.routerto access the live router instance and assert on its state (e.g.,harness.router.url). - Get Activated Components: Use
harness.getHarness(ComponentType)to get an instance of a component harness for the currently activated routed component, orharness.routeDebugElementto get theDebugElement. - Wait for Stability: After performing an action that causes navigation, always
await harness.fixture.whenStable()to ensure the routing is complete before making assertions.