typescript - Angular 6 - hogyan kell a router.events URL válaszát mockolni egységtesztben
Ahogy a cím is mutatja, egységtesztben kell megtévesztenem a router.events-et.
Az én komponensemben csinálok némi reguláris kifejezést, hogy megragadjam az első szövegrészletet a slash-ek között az URL-ben; pl. /pdp/
constructor(
private route: ActivatedRoute,
private router: Router,
}
this.router.events.pipe(takeUntil(this.ngUnsubscribe$))
.subscribe(route => {
if (route instanceof NavigationEnd) {
// debugger
this.projectType = route.url.match(/[a-z-]+/)[0];
}
});
Az egységtesztjeim hibát jeleznek, amikor az összetevőt építik: Cannot read property '0' of null. Amikor bekapcsolom a hibakeresőt, route úgy tűnik, nem megfelelően van beállítva, pedig az egységtesztben magában állítom be. Többféleképpen is próbáltam (inspirálva ettől a bejegyzéstől: Mocking router.events.subscribe() Angular2 és mások).
Első próbálkozás:
providers: [
{
provide: Router,
useValue: {
events: of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit'))
}
},
// ActivatedRoute also being mocked
{
provide: ActivatedRoute,
useValue: {
snapshot: { url: [{ path: 'new' }, { path: 'edit' }] },
parent: {
parent: {
snapshot: {
url: [
{ path: 'pdp' }
]
}
}
}
}
}
]
Második próbálkozás (a fenti bejegyzés alapján):
class MockRouter {
public events = of(new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit'))
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Harmadik próbálkozás (szintén a fenti bejegyzés alapján):
class MockRouter {
public ne = new NavigationEnd(0, '/pdp/project-details/4/edit', '/pdp/project-details/4/edit');
public events = new Observable(observer => {
observer.next(this.ne);
observer.complete();
});
}
providers: [
{
provide: Router,
useClass: MockRouter
}
]
Negyedik próbálkozás:
beforeEach(() => {
spyOn((<any>component).router, 'events').and.returnValue(of(new NavigationEnd(0, '/pdp/project-details/4/edit', 'pdp/project-details/4/edit')))
...
Ötödik kísérlet:
beforeEach(() => {
spyOn(TestBed.get(Router), 'events').and.returnValue(of({ url:'/pdp/project-details/4/edit' }))
...
A fentiek mindegyikében a route nincs beállítva; a NavigationEnd objektum egyenlő a következővel:
{ id: 1, url: "/", urlAfterRedirects: "/" }
Gondolatok?
Válasz #1
Olyan egyszerű is lehet, mint:
TestBed.configureTestingModule({
imports: [RouterTestingModule]
}).compileComponents()
...
const event = new NavigationEnd(42, '/', '/');
(TestBed.inject(Router).events as Subject<Event>).next(event);
Válasz #2
Itt van a válasz, amire rájöttem. Azt hiszem, egyszerűen nem terjesztettem ki eléggé az első megközelítést (fent):
import { of } from 'rxjs';
import { NavigationEnd, Router } from '@angular/router';
providers: [
{
provide: Router,
useValue: {
url: '/non-pdp/phases/8',
events: of(new NavigationEnd(0, 'http://localhost:4200/#/non-pdp/phases/8', 'http://localhost:4200/#/non-pdp/phases/8')),
navigate: jasmine.createSpy('navigate')
}
}
]
