Reputation: 6867
Am working on unit testing under my angular 4.0.0 app , some method in my real component is calling manual routing via :
method(){
....
this.navigateTo('/home/advisor');
....
}
with navigateTo is a custom routing method calling this :
public navigateTo(url: string) {
this.oldUrl = this.router.url;
this.router.navigate([url], { skipLocationChange: true });
}
i have this routing file :
import ... // Components and dependencies
const homeRoutes: Routes = [
{
path: 'home', component: HomeComponent,
children: [
{
path: 'registration',
component: RegistrationComponent,
children: [
{
path: 'synthese',
component: SyntheseComponent
},
{
path: 'queue',
component: QueueComponent,
children: [
{
path: 'queue-modal',
component: QueueModalComponent
},
{
path: 'confirm',
component: ConfirmComponent
}
]
}
]
},
{
path: 'toolbox',
component: ToolboxComponent
},
{
path: 'appointment',
component: AppointmentRegistrationComponent
},
{
path: 'appointment-validation',
component: AppointmentValidationComponent
},
{
path: 'datepicker',
component: DatePickerComponent
},
{
path: 'validation/:defaultNumber',
component: ValidationComponent,
children: [
{
path: 'synthese',
component: SyntheseComponent
}
]
},
{
path: 'modalField',
component: ModalFieldComponent
},
{
path: 'search',
component: SearchComponent
},
{
path: 'advanced-search',
component: AdvancedSearchComponent
},
{
path: 'tools',
component: ToolsComponent
},
{
path: 'advisor',
component: AdvisorComponent
},
{
path: 'pilote',
component: PilotComponent
},
{
path: 'blank',
component: BlankComponent
},
{
path: 'view-360/:id',
component: View360Component,
children: [
{
path: 'client',
component: ClientComponent
},
{
path: 'tools',
component: ToolsAdvisorComponent
},
{
path: 'valid-close',
component: ValidCloseComponent
},
{
path: 'application',
component: ApplicationView360Component
}
],
canActivate: [AuthGuardAdviser]
},
{
path: 'view-360',
component: View360Component,
children: [
{
path: 'client',
component: ClientComponent
}
],
canActivate: [AuthGuardAdviser]
},
{
path: 'contract',
component: ContractComponent
},
{
path: 'queue-again',
component: QueueAgainComponent
},
{
path: 'stock',
component: StockComponent,
children: [
{
path: 'mobile',
component: MobileComponent
},
{
path: 'stock-level',
component: StockLevelComponent
}
]
},
{
path: 'usefull-number',
component: UsefullNumberComponent
},
{
path: 'admin',
loadChildren: 'app/home/admin/admin.module#AdminModule',
// component: AdminComponent,
canActivate: [AuthGuardAdmin]
},
{
path: 'rb',
loadChildren: 'app/home/rb/rb.module#RbModule',
// component: RbComponent
// canActivate: [AuthGuardAdmin]
},
{
path: 'tools-advisor',
component: ToolsAdvisorComponent
},
{
path: 'catalog/:haveClient',
component: CatalogComponent
},
{
path: 'application',
component: ApplicationComponent
},
]
},
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(homeRoutes)
],
exports: [
RouterModule
],
declarations: []
})
export class HomeRoutingModule { }
Strangely , even my application goes fonctionnally well ,but the test throws this error :
Failed: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'home/advisor' Error: Cannot match any routes. URL Segment: 'home/advisor'
it seems like i have some missing configuration .
Any ideas ??
Upvotes: 40
Views: 55233
Reputation: 475
Since RouterTestingModule
in the accepted answer has since been deprecated, one accepted substitute is to use provideRouter()
.
You can do it by creating some mock routes for your test:
import { provideRouter } from "@angular/router";
...
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MyComponent],
providers: [provideRouter([{
path: "path/to/navigate",
redirectTo: "/"
}])]
}).compileComponents();
...
or import the actual routes:
import { routes } from "app/app.routes";
...
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [NavigationBarComponent],
providers: [provideRouter(routes)]
}).compileComponents();
...
Upvotes: 0
Reputation: 1
In my console, I am getting this error while running my unit test case because of SubRoute. I am able to fix this issue by implementing the following way in my unit test case.
class RouterStub {
url = '';
navigate(commands: any[], extras?: any) { }
}
beforeEach(async(() => {
TestBed.configureTestingModule({
providers:[{ provide: Router, useClass: RouterStub }]
}).compileComponents();
}));
Upvotes: 0
Reputation: 492
I run into same issue. The solution of accepted answer doesn't work for me, because I accidentally added the HttpClientModule instead of HttpClientTestingModule to my Spec files. To avoid the "Can not match any routes" issue be sure you add RouterTestingModule and HttpClientTestingModule everywhere it is needed.
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientTestingModule,
],
declarations: [
AppComponent
],
}).compileComponents();
}));
Upvotes: 4
Reputation: 57195
You need RouterTestingModule.withRoutes
like so:
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes(
[{path: 'yourpath', component: BlankComponent}]
)
],
declarations: [
BlankComponent,
YourComponentBeingTested
]
})
.compileComponents()
}))
Upvotes: 78
Reputation:
Following my comment :
When you want to unit test your router, you have to use the testing module, not the actual one.
Start with
import { RouterTestingModule } from '@angular/router/testing';
Then, in your Testbed
imports: [RouterTestingModule]
Now you should be able to unit test your component
EDIT
To make a spy on your routing, what you have to do is
spyOn(component.router, 'navigate').and.returnValue(true);
And you expect will look like
expect(component.router.navigate).toHaveBeenCalledWith('/home/advisor');
Upvotes: 31