docs: update testing components doc with generated compileComponent (#41947)
Updated testing-components-scenarios.md to match CLI generated test case. Closes #39740 PR Close #41947
This commit is contained in:
parent
3a5f006ca6
commit
2b939767fe
|
@ -1,7 +1,5 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion import-async
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
// #enddocregion import-async
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
|
@ -14,13 +12,13 @@ describe('BannerComponent (external files)', () => {
|
||||||
|
|
||||||
describe('Two beforeEach', () => {
|
describe('Two beforeEach', () => {
|
||||||
// #docregion async-before-each
|
// #docregion async-before-each
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed
|
TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
declarations: [BannerComponent],
|
declarations: [BannerComponent],
|
||||||
})
|
})
|
||||||
.compileComponents(); // compile template and css
|
.compileComponents(); // compile template and css
|
||||||
}));
|
});
|
||||||
// #enddocregion async-before-each
|
// #enddocregion async-before-each
|
||||||
|
|
||||||
// synchronous beforeEach
|
// synchronous beforeEach
|
||||||
|
@ -37,18 +35,14 @@ describe('BannerComponent (external files)', () => {
|
||||||
|
|
||||||
describe('One beforeEach', () => {
|
describe('One beforeEach', () => {
|
||||||
// #docregion one-before-each
|
// #docregion one-before-each
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed
|
await TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
|
||||||
declarations: [BannerComponent],
|
declarations: [BannerComponent],
|
||||||
})
|
}).compileComponents();
|
||||||
.compileComponents()
|
|
||||||
.then(() => {
|
|
||||||
fixture = TestBed.createComponent(BannerComponent);
|
fixture = TestBed.createComponent(BannerComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
h1 = fixture.nativeElement.querySelector('h1');
|
h1 = fixture.nativeElement.querySelector('h1');
|
||||||
});
|
});
|
||||||
}));
|
|
||||||
// #enddocregion one-before-each
|
// #enddocregion one-before-each
|
||||||
|
|
||||||
tests();
|
tests();
|
||||||
|
|
|
@ -12,8 +12,8 @@ describe('BannerComponent (inline template)', () => {
|
||||||
let h1: HTMLElement;
|
let h1: HTMLElement;
|
||||||
|
|
||||||
// #docregion configure-and-create
|
// #docregion configure-and-create
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ BannerComponent ],
|
declarations: [ BannerComponent ],
|
||||||
});
|
});
|
||||||
fixture = TestBed.createComponent(BannerComponent);
|
fixture = TestBed.createComponent(BannerComponent);
|
||||||
|
|
|
@ -50,10 +50,10 @@ function overrideSetup() {
|
||||||
beforeEach(() => activatedRoute.setParamMap({id: 99999}));
|
beforeEach(() => activatedRoute.setParamMap({id: 99999}));
|
||||||
|
|
||||||
// #docregion setup-override
|
// #docregion setup-override
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
await TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
imports: [HeroModule],
|
imports: [HeroModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
@ -74,17 +74,17 @@ function overrideSetup() {
|
||||||
// #enddocregion override-component-method
|
// #enddocregion override-component-method
|
||||||
|
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
});
|
||||||
// #enddocregion setup-override
|
// #enddocregion setup-override
|
||||||
|
|
||||||
// #docregion override-tests
|
// #docregion override-tests
|
||||||
let hdsSpy: HeroDetailServiceSpy;
|
let hdsSpy: HeroDetailServiceSpy;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
createComponent();
|
await createComponent();
|
||||||
// get the component's injected HeroDetailServiceSpy
|
// get the component's injected HeroDetailServiceSpy
|
||||||
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
|
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should have called `getHero`', () => {
|
it('should have called `getHero`', () => {
|
||||||
expect(hdsSpy.getHero.calls.count()).toBe(1, 'getHero called once');
|
expect(hdsSpy.getHero.calls.count()).toBe(1, 'getHero called once');
|
||||||
|
@ -133,10 +133,10 @@ const firstHero = getTestHeroes()[0];
|
||||||
|
|
||||||
function heroModuleSetup() {
|
function heroModuleSetup() {
|
||||||
// #docregion setup-hero-module
|
// #docregion setup-hero-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
await TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
imports: [HeroModule],
|
imports: [HeroModule],
|
||||||
// #enddocregion setup-hero-module
|
// #enddocregion setup-hero-module
|
||||||
|
@ -149,18 +149,18 @@ function heroModuleSetup() {
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
});
|
||||||
// #enddocregion setup-hero-module
|
// #enddocregion setup-hero-module
|
||||||
|
|
||||||
// #docregion route-good-id
|
// #docregion route-good-id
|
||||||
describe('when navigate to existing hero', () => {
|
describe('when navigate to existing hero', () => {
|
||||||
let expectedHero: Hero;
|
let expectedHero: Hero;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
expectedHero = firstHero;
|
expectedHero = firstHero;
|
||||||
activatedRoute.setParamMap({id: expectedHero.id});
|
activatedRoute.setParamMap({id: expectedHero.id});
|
||||||
createComponent();
|
await createComponent();
|
||||||
}));
|
});
|
||||||
|
|
||||||
// #docregion selected-tests
|
// #docregion selected-tests
|
||||||
it('should display that hero\'s name', () => {
|
it('should display that hero\'s name', () => {
|
||||||
|
@ -218,7 +218,9 @@ function heroModuleSetup() {
|
||||||
|
|
||||||
// #docregion route-no-id
|
// #docregion route-no-id
|
||||||
describe('when navigate with no hero id', () => {
|
describe('when navigate with no hero id', () => {
|
||||||
beforeEach(waitForAsync(createComponent));
|
beforeEach(async () => {
|
||||||
|
await createComponent();
|
||||||
|
});
|
||||||
|
|
||||||
it('should have hero.id === 0', () => {
|
it('should have hero.id === 0', () => {
|
||||||
expect(component.hero.id).toBe(0);
|
expect(component.hero.id).toBe(0);
|
||||||
|
@ -232,10 +234,10 @@ function heroModuleSetup() {
|
||||||
|
|
||||||
// #docregion route-bad-id
|
// #docregion route-bad-id
|
||||||
describe('when navigate to non-existent hero id', () => {
|
describe('when navigate to non-existent hero id', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
activatedRoute.setParamMap({id: 99999});
|
activatedRoute.setParamMap({id: 99999});
|
||||||
createComponent();
|
await createComponent();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should try to navigate back to hero list', () => {
|
it('should try to navigate back to hero list', () => {
|
||||||
expect(page.gotoListSpy.calls.any()).toBe(true, 'comp.gotoList called');
|
expect(page.gotoListSpy.calls.any()).toBe(true, 'comp.gotoList called');
|
||||||
|
@ -266,10 +268,10 @@ import { TitleCasePipe } from '../shared/title-case.pipe';
|
||||||
|
|
||||||
function formsModuleSetup() {
|
function formsModuleSetup() {
|
||||||
// #docregion setup-forms-module
|
// #docregion setup-forms-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
await TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
imports: [FormsModule],
|
imports: [FormsModule],
|
||||||
declarations: [HeroDetailComponent, TitleCasePipe],
|
declarations: [HeroDetailComponent, TitleCasePipe],
|
||||||
|
@ -280,7 +282,7 @@ function formsModuleSetup() {
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
});
|
||||||
// #enddocregion setup-forms-module
|
// #enddocregion setup-forms-module
|
||||||
|
|
||||||
it('should display 1st hero\'s name', waitForAsync(() => {
|
it('should display 1st hero\'s name', waitForAsync(() => {
|
||||||
|
@ -297,10 +299,10 @@ import { SharedModule } from '../shared/shared.module';
|
||||||
|
|
||||||
function sharedModuleSetup() {
|
function sharedModuleSetup() {
|
||||||
// #docregion setup-shared-module
|
// #docregion setup-shared-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
await TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
imports: [SharedModule],
|
imports: [SharedModule],
|
||||||
declarations: [HeroDetailComponent],
|
declarations: [HeroDetailComponent],
|
||||||
|
@ -311,7 +313,7 @@ function sharedModuleSetup() {
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
});
|
||||||
// #enddocregion setup-shared-module
|
// #enddocregion setup-shared-module
|
||||||
|
|
||||||
it('should display 1st hero\'s name', waitForAsync(() => {
|
it('should display 1st hero\'s name', waitForAsync(() => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion without-toBlob-macrotask
|
// #docregion without-toBlob-macrotask
|
||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
|
|
||||||
import { CanvasComponent } from './canvas.component';
|
import { CanvasComponent } from './canvas.component';
|
||||||
|
|
||||||
|
@ -17,13 +17,13 @@ describe('CanvasComponent', () => {
|
||||||
});
|
});
|
||||||
// #enddocregion enable-toBlob-macrotask
|
// #enddocregion enable-toBlob-macrotask
|
||||||
// #docregion without-toBlob-macrotask
|
// #docregion without-toBlob-macrotask
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async () => {
|
||||||
TestBed
|
await TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
declarations: [CanvasComponent],
|
declarations: [CanvasComponent],
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
});
|
||||||
|
|
||||||
it('should be able to generate blob data from canvas', fakeAsync(() => {
|
it('should be able to generate blob data from canvas', fakeAsync(() => {
|
||||||
const fixture = TestBed.createComponent(CanvasComponent);
|
const fixture = TestBed.createComponent(CanvasComponent);
|
||||||
|
|
|
@ -120,8 +120,8 @@ describe('TwainComponent', () => {
|
||||||
}));
|
}));
|
||||||
// #enddocregion fake-async-test
|
// #enddocregion fake-async-test
|
||||||
|
|
||||||
// #docregion async-test
|
// #docregion waitForAsync-test
|
||||||
it('should show quote after getQuote (async)', waitForAsync(() => {
|
it('should show quote after getQuote (waitForAsync)', waitForAsync(() => {
|
||||||
fixture.detectChanges(); // ngOnInit()
|
fixture.detectChanges(); // ngOnInit()
|
||||||
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
|
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ describe('TwainComponent', () => {
|
||||||
expect(errorMessage()).toBeNull('should not show error');
|
expect(errorMessage()).toBeNull('should not show error');
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
// #enddocregion async-test
|
// #enddocregion waitForAsync-test
|
||||||
|
|
||||||
|
|
||||||
// #docregion quote-done-test
|
// #docregion quote-done-test
|
||||||
|
|
|
@ -586,19 +586,11 @@ Then you can assert that the quote element displays the expected text.
|
||||||
To use `waitForAsync()` functionality, you must import `zone.js/testing` in your test setup file.
|
To use `waitForAsync()` functionality, you must import `zone.js/testing` in your test setup file.
|
||||||
If you created your project with the Angular CLI, `zone-testing` is already imported in `src/test.ts`.
|
If you created your project with the Angular CLI, `zone-testing` is already imported in `src/test.ts`.
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
The `TestBed.compileComponents()` method (see [below](#compile-components)) calls `XHR`
|
|
||||||
to read external template and css files during "just-in-time" compilation.
|
|
||||||
Write tests that call `compileComponents()` with the `waitForAsync()` utility.
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Here's the previous `fakeAsync()` test, re-written with the `waitForAsync()` utility.
|
Here's the previous `fakeAsync()` test, re-written with the `waitForAsync()` utility.
|
||||||
|
|
||||||
<code-example
|
<code-example
|
||||||
path="testing/src/app/twain/twain.component.spec.ts"
|
path="testing/src/app/twain/twain.component.spec.ts"
|
||||||
region="async-test">
|
region="waitForAsync-test">
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
The `waitForAsync()` utility hides some asynchronous boilerplate by arranging for the tester's code
|
The `waitForAsync()` utility hides some asynchronous boilerplate by arranging for the tester's code
|
||||||
|
@ -1502,7 +1494,7 @@ You must call `compileComponents()` within an asynchronous test function.
|
||||||
<div class="alert is-critical">
|
<div class="alert is-critical">
|
||||||
|
|
||||||
If you neglect to make the test function async
|
If you neglect to make the test function async
|
||||||
(e.g., forget to use `waitForAsync()` as described below),
|
(e.g., forget to use the `async` keyword as described below),
|
||||||
you'll see this error message
|
you'll see this error message
|
||||||
|
|
||||||
<code-example language="sh" class="code-shell" hideCopy>
|
<code-example language="sh" class="code-shell" hideCopy>
|
||||||
|
@ -1516,13 +1508,6 @@ A typical approach is to divide the setup logic into two separate `beforeEach()`
|
||||||
1. An async `beforeEach()` that compiles the components
|
1. An async `beforeEach()` that compiles the components
|
||||||
1. A synchronous `beforeEach()` that performs the remaining setup.
|
1. A synchronous `beforeEach()` that performs the remaining setup.
|
||||||
|
|
||||||
To follow this pattern, import the `waitForAsync()` helper with the other testing symbols.
|
|
||||||
|
|
||||||
<code-example
|
|
||||||
path="testing/src/app/banner/banner-external.component.spec.ts"
|
|
||||||
region="import-async">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
#### The async _beforeEach_
|
#### The async _beforeEach_
|
||||||
|
|
||||||
Write the first async `beforeEach` like this.
|
Write the first async `beforeEach` like this.
|
||||||
|
@ -1532,8 +1517,6 @@ Write the first async `beforeEach` like this.
|
||||||
region="async-before-each"
|
region="async-before-each"
|
||||||
header="app/banner/banner-external.component.spec.ts (async beforeEach)"></code-example>
|
header="app/banner/banner-external.component.spec.ts (async beforeEach)"></code-example>
|
||||||
|
|
||||||
The `waitForAsync()` helper function takes a parameterless function with the body of the setup.
|
|
||||||
|
|
||||||
The `TestBed.configureTestingModule()` method returns the `TestBed` class so you can chain
|
The `TestBed.configureTestingModule()` method returns the `TestBed` class so you can chain
|
||||||
calls to other `TestBed` static methods such as `compileComponents()`.
|
calls to other `TestBed` static methods such as `compileComponents()`.
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ So when IE is refreshed (manually or automatically by `ng serve`), sometimes the
|
||||||
|
|
||||||
## Appendix: Test using `fakeAsync()/waitForAsync()`
|
## Appendix: Test using `fakeAsync()/waitForAsync()`
|
||||||
|
|
||||||
If you use the `fakeAsync()/waitForAsync()` helper function to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/testing` in your test setup file.
|
If you use the `fakeAsync()/waitForAsync()` helper functions to run unit tests (for details, read the [Testing guide](guide/testing-components-scenarios#fake-async)), you need to import `zone.js/testing` in your test setup file.
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
If you create project with `Angular/CLI`, it is already imported in `src/test.ts`.
|
If you create project with `Angular/CLI`, it is already imported in `src/test.ts`.
|
||||||
|
|
Loading…
Reference in New Issue