Skip to content

Instantly share code, notes, and snippets.

@LayZeeDK
Created February 8, 2023 23:17
Show Gist options
  • Save LayZeeDK/e2350b4f839effac80d84fabd4840c39 to your computer and use it in GitHub Desktop.
Save LayZeeDK/e2350b4f839effac80d84fabd4840c39 to your computer and use it in GitHub Desktop.
Dashboard: Integrated routing component test suite.
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<a
*ngFor="let hero of heroes"
class="col-1-4"
routerLink="/detail/{{ hero.id }}"
>
<div class="module hero">
<h4>{{ hero.name }}</h4>
</div>
</a>
</div>
<app-hero-search></app-hero-search>
import { Location } from '@angular/common';
import { provideLocationMocks } from '@angular/common/testing';
import { Component, NgZone } from '@angular/core';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { RouterTestingHarness } from '@angular/router/testing';
import { asapScheduler, of } from 'rxjs';
import { observeOn } from 'rxjs/operators';
import { HeroService } from '../hero.service';
import { HEROES } from '../mock-heroes';
import { DashboardComponent } from './dashboard.component';
@Component({
standalone: true,
template: '',
})
class TestHeroDetailComponent {}
const leftMouseButton = 0;
describe('DashboardComponent (integrated)', () => {
async function setup() {
const fakeService = {
getHeroes() {
return of([...HEROES]).pipe(observeOn(asapScheduler));
},
} as Partial<HeroService>;
TestBed.configureTestingModule({
providers: [
provideRouter([
{
path: '',
pathMatch: 'full',
component: DashboardComponent,
},
{
path: 'detail/:id',
component: TestHeroDetailComponent,
},
]),
provideLocationMocks(),
{ provide: HeroService, useValue: fakeService },
],
});
const harness = await RouterTestingHarness.create();
const location = TestBed.inject(Location);
const ngZone = TestBed.inject(NgZone);
return {
advance() {
tick();
harness.detectChanges();
},
clickTopHero() {
const firstHeroLink = harness.routeDebugElement.query(By.css('a'));
ngZone.run(() =>
firstHeroLink.triggerEventHandler('click', {
button: leftMouseButton,
})
);
},
harness,
location,
};
}
it('navigates to the detail view when a hero link is clicked', fakeAsync(async () => {
const { advance, clickTopHero, harness, location } = await setup();
const component = await harness.navigateByUrl('/', DashboardComponent);
const [topHero] = component.heroes;
clickTopHero();
advance();
const expectedPath = '/detail/' + topHero.id;
expect(location.path())
.withContext('must navigate to the detail view for the top hero')
.toBe(expectedPath);
}));
});
import { NgFor } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { RouterLink } from '@angular/router';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { HeroSearchComponent } from '../hero-search/hero-search.component';
@Component({
standalone: true,
selector: 'app-dashboard',
imports: [NgFor, RouterLink, HeroSearchComponent],
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css'],
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService) {}
ngOnInit() {
this.getHeroes();
}
getHeroes(): void {
this.heroService
.getHeroes()
.subscribe(heroes => (this.heroes = heroes.slice(1, 5)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment