Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 7b5244c

Browse files
authored
docs(testing): more scenarios (#2396)
1 parent 1027e3e commit 7b5244c

20 files changed

+489
-180
lines changed

public/docs/_examples/testing/ts/app-specs.html

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
<script>
3232
var __spec_files__ = [
33+
'app/about.component.spec',
3334
'app/app.component.spec',
3435
'app/app.component.router.spec',
3536
'app/banner.component.spec',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { NO_ERRORS_SCHEMA } from '@angular/core';
2+
import { ComponentFixture, TestBed } from '@angular/core/testing';
3+
import { By } from '@angular/platform-browser';
4+
5+
import { AboutComponent } from './about.component';
6+
import { HighlightDirective } from './shared/highlight.directive';
7+
8+
let fixture: ComponentFixture<AboutComponent>;
9+
10+
describe('AboutComponent (highlightDirective)', () => {
11+
// #docregion tests
12+
beforeEach(() => {
13+
fixture = TestBed.configureTestingModule({
14+
declarations: [ AboutComponent, HighlightDirective],
15+
schemas: [ NO_ERRORS_SCHEMA ]
16+
})
17+
.createComponent(AboutComponent);
18+
fixture.detectChanges(); // initial binding
19+
});
20+
21+
it('should have skyblue <h2>', () => {
22+
const de = fixture.debugElement.query(By.css('h2'));
23+
expect(de.styles['backgroundColor']).toBe('skyblue');
24+
});
25+
// #enddocregion tests
26+
});
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
// #docregion
2-
import { Component } from '@angular/core';
3-
2+
import { Component } from '@angular/core';
43
@Component({
54
template: `
65
<h2 highlight="skyblue">About</h2>
76
<twain-quote></twain-quote>
8-
<p>All about this sample</p>
9-
`,
10-
styleUrls: ['app/shared/styles.css']
7+
<p>All about this sample</p>`
118
})
129
export class AboutComponent { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { NgModule } from '@angular/core';
2+
import { RouterModule } from '@angular/router';
3+
4+
import { AboutComponent } from './about.component';
5+
6+
@NgModule({
7+
imports: [
8+
RouterModule.forRoot([
9+
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'},
10+
{ path: 'about', component: AboutComponent },
11+
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'}
12+
])
13+
],
14+
exports: [ RouterModule ] // re-export the module declarations
15+
})
16+
export class AppRoutingModule { };

public/docs/_examples/testing/ts/app/app.component.html

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!-- #docregion -->
12
<app-banner></app-banner>
23
<app-welcome></app-welcome>
34

Original file line numberDiff line numberDiff line change
@@ -1,108 +1,94 @@
1+
// #docplaster
12
import { async, ComponentFixture, TestBed
23
} from '@angular/core/testing';
34

4-
import { NO_ERRORS_SCHEMA } from '@angular/core';
5+
import { DebugElement } from '@angular/core';
56
import { By } from '@angular/platform-browser';
67

7-
import { AppComponent } from './app.component';
8-
import { BannerComponent } from './banner.component';
9-
import { SharedModule } from './shared/shared.module';
10-
11-
import { Router, RouterStub, RouterLinkDirectiveStub, RouterOutletStubComponent
12-
} from '../testing';
13-
8+
// #docregion setup-schemas
9+
import { NO_ERRORS_SCHEMA } from '@angular/core';
10+
// #enddocregion setup-schemas
11+
// #docregion setup-stubs-w-imports
12+
import { Component } from '@angular/core';
13+
// #docregion setup-schemas
14+
import { AppComponent } from './app.component';
15+
// #enddocregion setup-schemas
16+
import { BannerComponent } from './banner.component';
17+
import { RouterLinkStubDirective } from '../testing';
18+
// #docregion setup-schemas
19+
import { RouterOutletStubComponent } from '../testing';
20+
21+
// #enddocregion setup-schemas
22+
@Component({selector: 'app-welcome', template: ''})
23+
class WelcomeStubComponent {}
24+
25+
// #enddocregion setup-stubs-w-imports
1426

1527
let comp: AppComponent;
1628
let fixture: ComponentFixture<AppComponent>;
1729

1830
describe('AppComponent & TestModule', () => {
31+
// #docregion setup-stubs, setup-stubs-w-imports
1932
beforeEach( async(() => {
2033
TestBed.configureTestingModule({
2134
declarations: [
22-
AppComponent, BannerComponent,
23-
RouterLinkDirectiveStub, RouterOutletStubComponent
24-
],
25-
providers: [{ provide: Router, useClass: RouterStub }],
26-
schemas: [NO_ERRORS_SCHEMA]
35+
AppComponent,
36+
BannerComponent, WelcomeStubComponent,
37+
RouterLinkStubDirective, RouterOutletStubComponent
38+
]
2739
})
2840

2941
.compileComponents()
30-
3142
.then(() => {
3243
fixture = TestBed.createComponent(AppComponent);
3344
comp = fixture.componentInstance;
3445
});
35-
3646
}));
37-
47+
// #enddocregion setup-stubs, setup-stubs-w-imports
3848
tests();
3949
});
4050

41-
function tests() {
42-
43-
it('can instantiate it', () => {
44-
expect(comp).not.toBeNull();
45-
});
46-
47-
it('can get RouterLinks from template', () => {
48-
fixture.detectChanges();
49-
50-
const links = fixture.debugElement
51-
// find all elements with an attached FakeRouterLink directive
52-
.queryAll(By.directive(RouterLinkDirectiveStub))
53-
// use injector to get the RouterLink directive instance attached to each element
54-
.map(de => de.injector.get(RouterLinkDirectiveStub) as RouterLinkDirectiveStub);
55-
56-
expect(links.length).toBe(3, 'should have 3 links');
57-
expect(links[0].linkParams).toBe('/dashboard', '1st link should go to Dashboard');
58-
expect(links[1].linkParams).toBe('/heroes', '1st link should go to Heroes');
59-
});
60-
61-
it('can click Heroes link in template', () => {
62-
fixture.detectChanges();
63-
64-
// Heroes RouterLink DebugElement
65-
const heroesLinkDe = fixture.debugElement
66-
.queryAll(By.directive(RouterLinkDirectiveStub))[1];
67-
68-
expect(heroesLinkDe).toBeDefined('should have a 2nd RouterLink');
69-
70-
const link = heroesLinkDe.injector.get(RouterLinkDirectiveStub) as RouterLinkDirectiveStub;
71-
72-
expect(link.navigatedTo).toBeNull('link should not have navigate yet');
73-
74-
heroesLinkDe.triggerEventHandler('click', null);
51+
//////// Testing w/ NO_ERRORS_SCHEMA //////
52+
describe('AppComponent & NO_ERRORS_SCHEMA', () => {
53+
// #docregion setup-schemas
54+
beforeEach( async(() => {
55+
TestBed.configureTestingModule({
56+
declarations: [ AppComponent, RouterLinkStubDirective ],
57+
schemas: [ NO_ERRORS_SCHEMA ]
58+
})
7559

76-
fixture.detectChanges();
77-
expect(link.navigatedTo).toBe('/heroes');
78-
});
79-
}
60+
.compileComponents()
61+
.then(() => {
62+
fixture = TestBed.createComponent(AppComponent);
63+
comp = fixture.componentInstance;
64+
});
65+
}));
66+
// #enddocregion setup-schemas
67+
tests();
68+
});
8069

8170
//////// Testing w/ real root module //////
82-
// Best to avoid
8371
// Tricky because we are disabling the router and its configuration
72+
// Better to use RouterTestingModule
8473
import { AppModule } from './app.module';
74+
import { AppRoutingModule } from './app-routing.module';
8575

8676
describe('AppComponent & AppModule', () => {
8777

8878
beforeEach( async(() => {
8979

9080
TestBed.configureTestingModule({
91-
imports: [ AppModule ],
92-
})
93-
94-
.overrideModule(AppModule, {
95-
// Must get rid of `RouterModule.forRoot` to prevent attempt to configure a router
96-
// Can't remove it because it doesn't have a known type (`forRoot` returns an object)
97-
// therefore, must reset the entire `imports` with just the necessary stuff
98-
set: { imports: [ SharedModule ]}
81+
imports: [ AppModule ]
9982
})
10083

101-
// Separate override because cannot both `set` and `add/remove` in same override
84+
// Get rid of app's Router configuration otherwise many failures.
85+
// Doing so removes Router declarations; add the Router stubs
10286
.overrideModule(AppModule, {
87+
remove: {
88+
imports: [ AppRoutingModule ]
89+
},
10390
add: {
104-
declarations: [ RouterLinkDirectiveStub, RouterOutletStubComponent ],
105-
providers: [{ provide: Router, useClass: RouterStub }]
91+
declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ]
10692
}
10793
})
10894

@@ -117,3 +103,46 @@ describe('AppComponent & AppModule', () => {
117103
tests();
118104
});
119105

106+
function tests() {
107+
let links: RouterLinkStubDirective[];
108+
let linkDes: DebugElement[];
109+
110+
// #docregion test-setup
111+
beforeEach(() => {
112+
// trigger initial data binding
113+
fixture.detectChanges();
114+
115+
// find DebugElements with an attached RouterLinkStubDirective
116+
linkDes = fixture.debugElement
117+
.queryAll(By.directive(RouterLinkStubDirective));
118+
119+
// get the attached link directive instances using the DebugElement injectors
120+
links = linkDes
121+
.map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
122+
});
123+
// #enddocregion test-setup
124+
125+
it('can instantiate it', () => {
126+
expect(comp).not.toBeNull();
127+
});
128+
129+
// #docregion tests
130+
it('can get RouterLinks from template', () => {
131+
expect(links.length).toBe(3, 'should have 3 links');
132+
expect(links[0].linkParams).toBe('/dashboard', '1st link should go to Dashboard');
133+
expect(links[1].linkParams).toBe('/heroes', '1st link should go to Heroes');
134+
});
135+
136+
it('can click Heroes link in template', () => {
137+
const heroesLinkDe = linkDes[1];
138+
const heroesLink = links[1];
139+
140+
expect(heroesLink.navigatedTo).toBeNull('link should not have navigated yet');
141+
142+
heroesLinkDe.triggerEventHandler('click', null);
143+
fixture.detectChanges();
144+
145+
expect(heroesLink.navigatedTo).toBe('/heroes');
146+
});
147+
// #docregion tests
148+
}

public/docs/_examples/testing/ts/app/app.component.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// #docregion
2-
import { Component } from '@angular/core';
3-
2+
import { Component } from '@angular/core';
43
@Component({
54
selector: 'my-app',
65
templateUrl: 'app/app.component.html'

public/docs/_examples/testing/ts/app/app.module.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { NgModule } from '@angular/core';
22
import { BrowserModule } from '@angular/platform-browser';
3-
import { RouterModule } from '@angular/router';
4-
53

64
import { AppComponent } from './app.component';
5+
import { AppRoutingModule } from './app-routing.module';
6+
77
import { AboutComponent } from './about.component';
88
import { BannerComponent } from './banner.component';
99
import { HeroService,
@@ -19,11 +19,7 @@ import { SharedModule } from './shared/shared.module';
1919
imports: [
2020
BrowserModule,
2121
DashboardModule,
22-
RouterModule.forRoot([
23-
{ path: '', redirectTo: 'dashboard', pathMatch: 'full'},
24-
{ path: 'about', component: AboutComponent },
25-
{ path: 'heroes', loadChildren: 'app/hero/hero.module#HeroModule'}
26-
]),
22+
AppRoutingModule,
2723
SharedModule
2824
],
2925
providers: [ HeroService, TwainService, UserService ],

public/docs/_examples/testing/ts/app/dashboard/dashboard.component.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { DashboardModule } from './dashboard.module';
1414

1515
// #docregion router-stub
1616
class RouterStub {
17-
navigateByUrl(url: string) { return url; }
17+
navigateByUrl(url: string) { return url; }
1818
}
1919
// #enddocregion router-stub
2020

public/docs/_examples/testing/ts/app/dashboard/dashboard.component.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ import { Hero, HeroService } from '../model';
77
@Component({
88
selector: 'app-dashboard',
99
templateUrl: 'app/dashboard/dashboard.component.html',
10-
styleUrls: [
11-
'app/shared/styles.css',
12-
'app/dashboard/dashboard.component.css'
13-
]
10+
styleUrls: ['app/dashboard/dashboard.component.css']
1411
})
1512
export class DashboardComponent implements OnInit {
1613

public/docs/_examples/testing/ts/app/hero/hero-detail.component.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class Page {
187187
const router = compInjector.get(Router);
188188
this.gotoSpy = spyOn(comp, 'gotoList').and.callThrough();
189189
this.saveSpy = spyOn(hds, 'saveHero').and.callThrough();
190-
this.navSpy = spyOn(router, 'navigate').and.callThrough();
190+
this.navSpy = spyOn(router, 'navigate');
191191
}
192192

193193
/** Add page elements after hero arrives */

public/docs/_examples/testing/ts/app/hero/hero-detail.component.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ import { HeroDetailService } from './hero-detail.service';
88
@Component({
99
selector: 'app-hero-detail',
1010
templateUrl: 'app/hero/hero-detail.component.html',
11-
styleUrls: [
12-
'app/shared/styles.css',
13-
'app/hero/hero-detail.component.css'
14-
],
11+
styleUrls: ['app/hero/hero-detail.component.css'],
1512
providers: [ HeroDetailService ]
1613
})
1714
export class HeroDetailComponent implements OnInit {

public/docs/_examples/testing/ts/app/hero/hero-list.component.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Page {
132132

133133
// Get the component's injected router and spy on it
134134
const router = fixture.debugElement.injector.get(Router);
135-
this.navSpy = spyOn(router, 'navigate').and.callThrough();
135+
this.navSpy = spyOn(router, 'navigate');
136136
};
137137
}
138138

public/docs/_examples/testing/ts/app/hero/hero-list.component.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ import { Hero, HeroService } from '../model';
66
@Component({
77
selector: 'app-heroes',
88
templateUrl: 'app/hero/hero-list.component.html',
9-
styleUrls: [
10-
'app/shared/styles.css',
11-
'app/hero/hero-list.component.css'
12-
]
9+
styleUrls: ['app/hero/hero-list.component.css']
1310
})
1411
export class HeroListComponent implements OnInit {
1512
heroes: Promise<Hero[]>;

0 commit comments

Comments
 (0)