Ecco una soluzione alternativa, che è un po 'più prolisso ma ci permette di utilizzare SpyLocation al fine di verificare i cambiamenti di rotta. Per prima cosa creiamo provider di router di prova generici.
router-test-providers.ts
import { ComponentResolver } from '@angular/core';
import { Type } from '@angular/core/src/facade/lang';
import { SpyLocation } from '@angular/common/testing';
import { Location } from '@angular/common';
import { Router, RouterOutletMap } from '@angular/router';
import { RouteSegment } from '@angular/router/src/segments';
import { RouterUrlSerializer, DefaultRouterUrlSerializer } from '@angular/router/src/router_url_serializer';
/**
* this class provides the means of loading the tested component type
*/
export class FakeRootComponentLoader {
constructor(private rootComponentType: Type) {
this.rootComponentType = rootComponentType;
}
public getRootComponentType =() => {
return this.rootComponentType;
}
}
let routerFactory = function (
fakeRootComponentLoader: FakeRootComponentLoader,
componentResolver: ComponentResolver,
urlSerializer: RouterUrlSerializer,
routerOutletMap: RouterOutletMap,
location: Location): Router
{
let fakeRootComponentType = fakeRootComponentLoader.getRootComponentType();
/**
* _rootComponent should not be null, but it is what in angular2 rc.1 code
* so we replicate the behaviour
*/
return new Router(
null,
fakeRootComponentType,
componentResolver,
urlSerializer,
routerOutletMap,
location);
};
export const ROUTER_TEST_PROVIDERS: any[] = [
{provide: RouterUrlSerializer, useClass: DefaultRouterUrlSerializer},
RouterOutletMap,
{provide: Location, useClass: SpyLocation},
{provide: RouteSegment, useFactory: (r) => r.routeTree.root, deps: [Router]},
{
provide: Router,
useFactory: routerFactory,
deps: [FakeRootComponentLoader, ComponentResolver, RouterUrlSerializer, RouterOutletMap, Location]
}
];
Il test gelsomino corrispondente è fornita di seguito.
navigation.spec.ts
import { Component } from '@angular/core';
import { beforeEach, beforeEachProviders, inject } from '@angular/core/testing';
import { ROUTER_DIRECTIVES, Route, Routes, Router } from '@angular/router';
import { TestComponentBuilder } from '@angular/compiler/testing';
import { Location } from '@angular/common';
import { ROUTER_TEST_PROVIDERS, FakeRootComponentLoader } from './router-test-providers';
/**
* We inject router into the EmptyComponent,
* Due to the way DI works in angular2, if we import the ROUTER_TEST_PROVIDERS,
* and inject the Router, we will get our own implementation of the Router injected.
*/
@Component({selector: 'empty-component', template: `empty`})
@Component({
selector: 'empty-component',
template: `empty`,
directives: [ROUTER_DIRECTIVES]
})
class EmptyComponent {
constructor (private router: Router){ }
public getRouter() {return this.router;}
}
@Component({
selector: 'root-component',
template: `<router-outlet></router-outlet>`,
directives: [ROUTER_DIRECTIVES]
})
@Routes([new Route({path: '/login', component: EmptyComponent})])
class RootComponent { }
describe('navigation',() => {
beforeEachProviders(() => [
{
provide: FakeRootComponentLoader,
useFactory:() => new FakeRootComponentLoader(RootComponent)
},
ROUTER_TEST_PROVIDERS,
EmptyComponent
]);
let location: Location;
let testCb: TestComponentBuilder;
let emptyComp: EmptyComponent;
beforeEach(inject([Location, TestComponentBuilder, EmptyComponent], (loc, tcb, emptyCt) => {
location = loc;
testCb = tcb;
emptyComp = emptyCt;
}));
it('should be defined',() => {
expect(EmptyComponent).toBeDefined();
});
it('Should navigate to login', (done) => {
expect(location.path()).toEqual('');
testCb.createAsync(RootComponent).then(fixture => {
emptyComp.getRouter().navigate(['login']).then(() => {
fixture.detectChanges();
expect(location.path()).toBe('/login');
done();
}).catch(e => done.fail(e));
});
});
});
Ci sono momenti in cui la risposta è così semplice che non puoi vederla. ** (facepalm) **. È fantastico! Soluzione semplice ma efficace! Grazie! – hartpdx
Bella soluzione, grazie! –