Looking at previous similar questions, it doesn't seem that there was ever a clear answer for this.
Here's what's happening. I'm building an angular2 app using the angular-cli tool (beta 16 running, with angular 2.0.1 and router 3.0.1.
When I run "ng test" all my tests pass, expect my app.component. (ng serve is working fine etc)
Here's some code:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { HealthComponent } from './health/health.component';
import { MonitorModule } from './monitor/monitor.module';
import { PlanComponent } from './plan/plan.component';
import { ConfigureComponent } from './configure/configure.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TroubleshootComponent } from './troubleshoot/troubleshoot.component';
import { HeaderComponent } from './ui/header/header.component';
import { OnboardingModule } from './onboarding/onboarding.module';
import { routing, appRoutingProviders } from './app.routing';
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
routing,
MonitorModule,
OnboardingModule
],
declarations: [
AppComponent,
HomeComponent,
HealthComponent,
PlanComponent,
ConfigureComponent,
DashboardComponent,
TroubleshootComponent,
HeaderComponent
],
providers: [
appRoutingProviders
],
bootstrap: [AppComponent]
})
export class AppModule {
}
app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
}
app.component.spec.ts
/* tslint:disable:no-unused-variable */
import { TestBed, async } from '@angular/core/testing';
import { APP_BASE_HREF } from '@angular/common';
import { routing, appRoutingProviders } from './app.routing';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { HeaderComponent } from './ui/header/header.component';
import { HealthComponent } from './health/health.component';
import { PlanComponent } from './plan/plan.component';
import { ConfigureComponent } from './configure/configure.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { TroubleshootComponent } from './troubleshoot/troubleshoot.component';
describe('App: Ng2Test2', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent,
HeaderComponent,
HomeComponent,
HealthComponent,
PlanComponent,
ConfigureComponent,
DashboardComponent,
TroubleshootComponent
],
imports: [
routing
],
providers: [
appRoutingProviders,
{ provide: APP_BASE_HREF, useValue : '/' }
]
});
});
it('should create the app', async(() => {
let fixture = TestBed.createComponent(AppComponent);
let app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
}));
});
app.component.html
<app-header></app-header>
<router-outlet></router-outlet>
Finally, here's the error I'm getting when I run "ng test":
App: Ng2Test2 should create the app FAILED
Failed: Error in ./AppComponent class AppComponent - inline template:2:2 caused by: Bootstrap at least one component before injecting Router.
Error: Bootstrap at least one component before injecting Router.
at setupRouter (webpack:///Users/jtaylor/Projects/hmng-angular/hmng-ng2/~/@angular/router/src/router_module.js:190:0 <- src/test.ts:29132:15)
I've tried a ton of different things to prevent this error, but can't get this one to stop firing!
Any thoughts on this?
EDIT: I tracked it down to this component, where I use router in my constructor:
header.component.ts
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { AppComponent } from '../../app.component';
@Component({
selector: 'app-header',
templateUrl: './header.component.html'
})
export class HeaderComponent implements OnInit {
section: any;
// router: Router;
// activateRoute: ActivatedRoute;
constructor(
public router: Router,
public activatedRoute: ActivatedRoute
) {}
ngOnInit() {
this.router.events.subscribe(e => {
if (e instanceof NavigationEnd) {
this.setActiveNavTab(e.url.replace(/^\/([^\/]*).*$/, '$1'));
}
});
}
setActiveNavTab(section: string) {
this.section = section;
}
}
So, how can I bootstrap a component before that constructor with the unit test?
It's because you are trying to use the RouterModule
for the test. Instead you should use the RouterTestingModule
and add your routes with RouterTestingModule.withRoutes
import { RouterTestingModule } from '@angular/router/testing';
imports: [
// routing
RouterTestingModule.withRoutes(APP_ROUTES)
]