Files
ECC/pi/core/skills/angular-developer/references/router-testing.md
T
Affaan MustafaandGitHub c70874fae9 feat(pi): curated pi/core skills+prompts profile, CI load test, and 2.2.2 release sync (#3264)
Adds a curated, Pi-native, skills+prompts-only profile at pi/core/ for downstream packagers that mirror GitHub Releases.

- manifests/pi-core.json: explicit include lists, per-item exclusion reasons, curation rules, safety allowlists; every root skill and command must be classified.
- scripts/build-pi-core.js regenerates pi/core deterministically (package.json from VERSION, LICENSE, README.md, CURATION.md, skills/, commands/); --check fails CI on drift. council is renamed ecc-council inside pi/core only.
- Safety checks: no callable endpoints outside the allowlist, no npx/curl|sh/pip install, no secrets, no absolute home paths, no symlinks, valid frontmatter, no duplicate names.
- CI: build + drift check and an offline Pi CLI load test of pi/core.
- Release: VERSION, package.json and pi/core/package.json at 2.2.2, CHANGELOG, tag-triggered release verification, and a two-week cadence in CONTRIBUTING.md.

pi/core: 123 of 293 skills and 24 of 94 commands; 35,006 characters of skill description text.
2026-09-29 20:24:05 -05:00

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

  1. provideRouter([...]): Provide a test-specific routing configuration. This should include the routes necessary for the component-under-test to function correctly.
  2. 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.router to 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, or harness.routeDebugElement to get the DebugElement.
  • Wait for Stability: After performing an action that causes navigation, always await harness.fixture.whenStable() to ensure the routing is complete before making assertions.