docs(testing): explain rationale for stubbed routerLink tests (#2422)
This commit is contained in:
parent
0f99a7c130
commit
55bf126489
|
@ -11,7 +11,7 @@ block includes
|
||||||
Along the way you will learn some general testing principles and techniques but the focus is on
|
Along the way you will learn some general testing principles and techniques but the focus is on
|
||||||
Angular testing.
|
Angular testing.
|
||||||
|
|
||||||
a#top
|
#top
|
||||||
:marked
|
:marked
|
||||||
# Table of Contents
|
# Table of Contents
|
||||||
1. [Introduction to Angular Testing](#testing-intro)
|
1. [Introduction to Angular Testing](#testing-intro)
|
||||||
|
@ -83,7 +83,7 @@ a#top
|
||||||
a(href="#top").to-top Back to top
|
a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
a#testing-intro
|
#testing-intro
|
||||||
:marked
|
:marked
|
||||||
# Introduction to Angular Testing
|
# Introduction to Angular Testing
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ table(width="100%")
|
||||||
and assert that the application responds in the browser as expected.
|
and assert that the application responds in the browser as expected.
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
a#setup
|
#setup
|
||||||
:marked
|
:marked
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ a#setup
|
||||||
you can skip the rest of this section and get on with your first test.
|
you can skip the rest of this section and get on with your first test.
|
||||||
The QuickStart repo provides all necessary setup.
|
The QuickStart repo provides all necessary setup.
|
||||||
|
|
||||||
a#setup-files
|
#setup-files
|
||||||
:marked
|
:marked
|
||||||
### Setup files
|
### Setup files
|
||||||
Here's brief description of the setup files.
|
Here's brief description of the setup files.
|
||||||
|
@ -247,7 +247,7 @@ table(width="100%")
|
||||||
They were installed when you ran `npm install`.
|
They were installed when you ran `npm install`.
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
a#1st-karma-test
|
#1st-karma-test
|
||||||
:marked
|
:marked
|
||||||
# The first karma test
|
# The first karma test
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ figure.image-display
|
||||||
a(href="#top").to-top Back to top
|
a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
a#atp-intro
|
#atp-intro
|
||||||
:marked
|
:marked
|
||||||
# The Angular Testing Platform (ATP)
|
# The Angular Testing Platform (ATP)
|
||||||
|
|
||||||
|
@ -439,7 +439,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#sample-app
|
#sample-app
|
||||||
:marked
|
:marked
|
||||||
# The sample application and its tests
|
# The sample application and its tests
|
||||||
|
|
||||||
|
@ -460,7 +460,7 @@ a#sample-app
|
||||||
a(href="#top").to-top Back to top
|
a(href="#top").to-top Back to top
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#simple-component-test
|
#simple-component-test
|
||||||
:marked
|
:marked
|
||||||
# Test a component
|
# Test a component
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ a#simple-component-test
|
||||||
Start with ES6 import statements to get access to symbols referenced in the spec.
|
Start with ES6 import statements to get access to symbols referenced in the spec.
|
||||||
+makeExample('testing/ts/app/banner.component.spec.ts', 'imports', 'app/banner.component.spec.ts (imports)')(format='.')
|
+makeExample('testing/ts/app/banner.component.spec.ts', 'imports', 'app/banner.component.spec.ts (imports)')(format='.')
|
||||||
|
|
||||||
a#configure-testing-module
|
#configure-testing-module
|
||||||
:marked
|
:marked
|
||||||
Here's the setup for the tests followed by observations about the `beforeEach`:
|
Here's the setup for the tests followed by observations about the `beforeEach`:
|
||||||
+makeExample('testing/ts/app/banner.component.spec.ts', 'setup', 'app/banner.component.spec.ts (setup)')(format='.')
|
+makeExample('testing/ts/app/banner.component.spec.ts', 'setup', 'app/banner.component.spec.ts (setup)')(format='.')
|
||||||
|
@ -492,7 +492,7 @@ a#configure-testing-module
|
||||||
But that would lead to tons more configuration in order to support the other components within `AppModule`
|
But that would lead to tons more configuration in order to support the other components within `AppModule`
|
||||||
that have nothing to do with `BannerComponent`.
|
that have nothing to do with `BannerComponent`.
|
||||||
|
|
||||||
a#create-component
|
#create-component
|
||||||
:marked
|
:marked
|
||||||
`TestBed.createComponent` creates an instance of `BannerComponent` to test.
|
`TestBed.createComponent` creates an instance of `BannerComponent` to test.
|
||||||
The method returns a `ComponentFixture`, a handle on the test environment surrounding the created component.
|
The method returns a `ComponentFixture`, a handle on the test environment surrounding the created component.
|
||||||
|
@ -516,7 +516,7 @@ a#create-component
|
||||||
:markdown
|
:markdown
|
||||||
These tests ask the `DebugElement` for the native HTML element to satisfy their expectations.
|
These tests ask the `DebugElement` for the native HTML element to satisfy their expectations.
|
||||||
|
|
||||||
a#detect-changes
|
#detect-changes
|
||||||
:marked
|
:marked
|
||||||
### _detectChanges_: Angular change detection under test
|
### _detectChanges_: Angular change detection under test
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ a#detect-changes
|
||||||
It gives the tester an opportunity to investigate the state of
|
It gives the tester an opportunity to investigate the state of
|
||||||
the component _before Angular initiates data binding or calls lifecycle hooks_.
|
the component _before Angular initiates data binding or calls lifecycle hooks_.
|
||||||
|
|
||||||
a#auto-detect-changes
|
#auto-detect-changes
|
||||||
:marked
|
:marked
|
||||||
### Automatic change detection
|
### Automatic change detection
|
||||||
Some testers prefer that the Angular test environment run change detection automatically.
|
Some testers prefer that the Angular test environment run change detection automatically.
|
||||||
|
@ -570,7 +570,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#component-with-dependency
|
#component-with-dependency
|
||||||
:marked
|
:marked
|
||||||
# Test a component with a dependency
|
# Test a component with a dependency
|
||||||
Components often have service dependencies.
|
Components often have service dependencies.
|
||||||
|
@ -605,7 +605,7 @@ a#component-with-dependency
|
||||||
and its tests:
|
and its tests:
|
||||||
+makeExample('testing/ts/app/welcome.component.spec.ts', 'user-service-stub')(format='.')
|
+makeExample('testing/ts/app/welcome.component.spec.ts', 'user-service-stub')(format='.')
|
||||||
|
|
||||||
a#injected-service-reference
|
#injected-service-reference
|
||||||
:marked
|
:marked
|
||||||
## Referencing injected services
|
## Referencing injected services
|
||||||
The tests need access to the injected (stubbed) `UserService`.
|
The tests need access to the injected (stubbed) `UserService`.
|
||||||
|
@ -641,7 +641,7 @@ a#injected-service-reference
|
||||||
.alert.is-important
|
.alert.is-important
|
||||||
:marked
|
:marked
|
||||||
Use the component's own injector to get the component's injected service.
|
Use the component's own injector to get the component's injected service.
|
||||||
a#welcome-spec-setup
|
#welcome-spec-setup
|
||||||
:marked
|
:marked
|
||||||
Here's the complete, preferred `beforeEach`:
|
Here's the complete, preferred `beforeEach`:
|
||||||
+makeExample('testing/ts/app/welcome.component.spec.ts', 'setup', 'app/welcome.component.spec.ts')(format='.')
|
+makeExample('testing/ts/app/welcome.component.spec.ts', 'setup', 'app/welcome.component.spec.ts')(format='.')
|
||||||
|
@ -658,7 +658,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#component-with-async-service
|
#component-with-async-service
|
||||||
:marked
|
:marked
|
||||||
# Test a component with an async service
|
# Test a component with an async service
|
||||||
Many services return values asynchronously.
|
Many services return values asynchronously.
|
||||||
|
@ -677,7 +677,7 @@ a#component-with-async-service
|
||||||
They should emulate such calls. The setup in this `app/shared/twain.component.spec.ts` shows one way to do that:
|
They should emulate such calls. The setup in this `app/shared/twain.component.spec.ts` shows one way to do that:
|
||||||
+makeExample('testing/ts/app/shared/twain.component.spec.ts', 'setup', 'app/shared/twain.component.spec.ts (setup)')(format='.')
|
+makeExample('testing/ts/app/shared/twain.component.spec.ts', 'setup', 'app/shared/twain.component.spec.ts (setup)')(format='.')
|
||||||
|
|
||||||
a#service-spy
|
#service-spy
|
||||||
:marked
|
:marked
|
||||||
### Spying on the real service
|
### Spying on the real service
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ a#service-spy
|
||||||
|
|
||||||
The test must become an "async test" ... like the third test
|
The test must become an "async test" ... like the third test
|
||||||
|
|
||||||
a#async
|
#async
|
||||||
:marked
|
:marked
|
||||||
## The _async_ function in _it_
|
## The _async_ function in _it_
|
||||||
|
|
||||||
|
@ -731,7 +731,7 @@ a#async
|
||||||
Some functions called within a test (such as `fixture.whenStable`) continue to reveal their asynchronous behavior.
|
Some functions called within a test (such as `fixture.whenStable`) continue to reveal their asynchronous behavior.
|
||||||
Consider also the [_fakeAsync_](#fake-async) alternative which affords a more linear coding experience.
|
Consider also the [_fakeAsync_](#fake-async) alternative which affords a more linear coding experience.
|
||||||
|
|
||||||
a#when-stable
|
#when-stable
|
||||||
:marked
|
:marked
|
||||||
## _whenStable_
|
## _whenStable_
|
||||||
The test must wait for the `getQuote` promise to resolve.
|
The test must wait for the `getQuote` promise to resolve.
|
||||||
|
@ -754,8 +754,8 @@ a#when-stable
|
||||||
The test kicks off another round of change detection (`fixture.detechChanges`) which tells Angular to update the DOM with the quote.
|
The test kicks off another round of change detection (`fixture.detechChanges`) which tells Angular to update the DOM with the quote.
|
||||||
The `getQuote` helper method extracts the display element text and the expectation confirms that the text matches the test quote.
|
The `getQuote` helper method extracts the display element text and the expectation confirms that the text matches the test quote.
|
||||||
|
|
||||||
a#fakeAsync
|
#fakeAsync
|
||||||
a#fake-async
|
#fake-async
|
||||||
:marked
|
:marked
|
||||||
## The _fakeAsync_ function
|
## The _fakeAsync_ function
|
||||||
|
|
||||||
|
@ -776,8 +776,8 @@ a#fake-async
|
||||||
|
|
||||||
There are limitations. For example, you cannot make an XHR call from within a `fakeAsync`.
|
There are limitations. For example, you cannot make an XHR call from within a `fakeAsync`.
|
||||||
|
|
||||||
a#tick
|
#tick
|
||||||
a#tick-first-look
|
#tick-first-look
|
||||||
:marked
|
:marked
|
||||||
## The _tick_ function
|
## The _tick_ function
|
||||||
Compare the third and fourth tests. Notice that `fixture.whenStable` is gone, replaced by `tick()`.
|
Compare the third and fourth tests. Notice that `fixture.whenStable` is gone, replaced by `tick()`.
|
||||||
|
@ -795,7 +795,7 @@ a#tick-first-look
|
||||||
To more fully appreciate the improvement, imagine a succession of asynchronous operations,
|
To more fully appreciate the improvement, imagine a succession of asynchronous operations,
|
||||||
chained in a long sequence of promise callbacks.
|
chained in a long sequence of promise callbacks.
|
||||||
|
|
||||||
a#jasmine-done
|
#jasmine-done
|
||||||
:marked
|
:marked
|
||||||
## _jasmine.done_
|
## _jasmine.done_
|
||||||
|
|
||||||
|
@ -819,7 +819,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#component-with-external-template
|
#component-with-external-template
|
||||||
:marked
|
:marked
|
||||||
# Test a component with an external template
|
# Test a component with an external template
|
||||||
The `TestBed.createComponent` is a synchronous method.
|
The `TestBed.createComponent` is a synchronous method.
|
||||||
|
@ -847,7 +847,7 @@ a#component-with-external-template
|
||||||
The `app/dashboard/dashboard-hero.component.spec.ts` demonstrates the pre-compilation process:
|
The `app/dashboard/dashboard-hero.component.spec.ts` demonstrates the pre-compilation process:
|
||||||
+makeExample('testing/ts/app/dashboard/dashboard-hero.component.spec.ts', 'compile-components', 'app/dashboard/dashboard-hero.component.spec.ts (compileComponents)')(format='.')
|
+makeExample('testing/ts/app/dashboard/dashboard-hero.component.spec.ts', 'compile-components', 'app/dashboard/dashboard-hero.component.spec.ts (compileComponents)')(format='.')
|
||||||
|
|
||||||
a#async-in-before-each
|
#async-in-before-each
|
||||||
:marked
|
:marked
|
||||||
## The _async_ function in _beforeEach_
|
## The _async_ function in _beforeEach_
|
||||||
|
|
||||||
|
@ -855,7 +855,7 @@ a#async-in-before-each
|
||||||
The `async` function arranges for the tester's code to run in a special _async test zone_
|
The `async` function arranges for the tester's code to run in a special _async test zone_
|
||||||
that hides the mechanics of asynchronous execution, just as it does when passed to an [_it_ test)(#async).
|
that hides the mechanics of asynchronous execution, just as it does when passed to an [_it_ test)(#async).
|
||||||
|
|
||||||
a#compile-components
|
#compile-components
|
||||||
:marked
|
:marked
|
||||||
## _compileComponents_
|
## _compileComponents_
|
||||||
In this example, `Testbed.compileComponents` compiles one component, the `DashboardComponent`.
|
In this example, `Testbed.compileComponents` compiles one component, the `DashboardComponent`.
|
||||||
|
@ -884,7 +884,7 @@ a#compile-components
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#component-with-inputs-outputs
|
#component-with-inputs-outputs
|
||||||
:marked
|
:marked
|
||||||
# Test a component with inputs and outputs
|
# Test a component with inputs and outputs
|
||||||
A component with inputs and outputs typically appears inside the view template of a host component.
|
A component with inputs and outputs typically appears inside the view template of a host component.
|
||||||
|
@ -971,7 +971,7 @@ a#component-with-inputs-outputs
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#component-inside-test-host
|
#component-inside-test-host
|
||||||
:marked
|
:marked
|
||||||
# Test a component inside a test host component
|
# Test a component inside a test host component
|
||||||
|
|
||||||
|
@ -1015,7 +1015,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#routed-component
|
#routed-component
|
||||||
:marked
|
:marked
|
||||||
# Test a routed component
|
# Test a routed component
|
||||||
|
|
||||||
|
@ -1041,7 +1041,7 @@ a#routed-component
|
||||||
The following test clicks the displayed hero and confirms (with the help of a spy) that `Router.navigateByUrl` is called with the expected url.
|
The following test clicks the displayed hero and confirms (with the help of a spy) that `Router.navigateByUrl` is called with the expected url.
|
||||||
+makeExample('testing/ts/app/dashboard/dashboard.component.spec.ts', 'navigate-test', 'app/dashboard/dashboard.component.spec.ts (navigate test)')(format='.')
|
+makeExample('testing/ts/app/dashboard/dashboard.component.spec.ts', 'navigate-test', 'app/dashboard/dashboard.component.spec.ts (navigate test)')(format='.')
|
||||||
|
|
||||||
a#inject
|
#inject
|
||||||
:marked
|
:marked
|
||||||
## The _inject_ function
|
## The _inject_ function
|
||||||
|
|
||||||
|
@ -1083,7 +1083,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#routed-component-w-param
|
#routed-component-w-param
|
||||||
:marked
|
:marked
|
||||||
# Test a routed component with parameters
|
# Test a routed component with parameters
|
||||||
|
|
||||||
|
@ -1117,7 +1117,7 @@ a#routed-component-w-param
|
||||||
By now you know how to stub the `Router` and a data service.
|
By now you know how to stub the `Router` and a data service.
|
||||||
Stubbing the `ActivatedRoute` would follow the same pattern except for a complication:
|
Stubbing the `ActivatedRoute` would follow the same pattern except for a complication:
|
||||||
the `ActivatedRoute.params` is an _Observable_.
|
the `ActivatedRoute.params` is an _Observable_.
|
||||||
a#stub-observable
|
#stub-observable
|
||||||
:marked
|
:marked
|
||||||
### _Observable_ test double
|
### _Observable_ test double
|
||||||
|
|
||||||
|
@ -1148,7 +1148,7 @@ a#stub-observable
|
||||||
:marked
|
:marked
|
||||||
The router stubs in this chapter are meant to inspire you. Create your own stubs to fit your testing needs.
|
The router stubs in this chapter are meant to inspire you. Create your own stubs to fit your testing needs.
|
||||||
|
|
||||||
a#observable-tests
|
#observable-tests
|
||||||
:marked
|
:marked
|
||||||
### _Observable_ tests
|
### _Observable_ tests
|
||||||
Here's a test demonstrating the component's behavior when the observed `id` refers to an existing hero:
|
Here's a test demonstrating the component's behavior when the observed `id` refers to an existing hero:
|
||||||
|
@ -1177,7 +1177,7 @@ a#observable-tests
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#page-object
|
#page-object
|
||||||
:marked
|
:marked
|
||||||
# Use a _page_ object to simplify setup
|
# Use a _page_ object to simplify setup
|
||||||
|
|
||||||
|
@ -1214,24 +1214,23 @@ figure.image-display
|
||||||
a(href="#top").to-top Back to top
|
a(href="#top").to-top Back to top
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#router-outlet-component
|
#router-outlet-component
|
||||||
:marked
|
:marked
|
||||||
# Test a _RouterOutlet_ component
|
# Test a _RouterOutlet_ component
|
||||||
|
|
||||||
The `AppComponent` displays routed components in a `<router-outlet>`.
|
The `AppComponent` displays routed components in a `<router-outlet>`.
|
||||||
It also displays a navigation bar with anchors and their `RouterLink` directives.
|
It also displays a navigation bar with anchors and their `RouterLink` directives.
|
||||||
a#app-component-html
|
#app-component-html
|
||||||
+makeExample('testing/ts/app/app.component.html', '', 'app/app.component.html')(format='.')
|
+makeExample('testing/ts/app/app.component.html', '', 'app/app.component.html')(format='.')
|
||||||
:marked
|
:marked
|
||||||
The component class does nothing.
|
The component class does nothing.
|
||||||
+makeExample('testing/ts/app/app.component.ts', '', 'app/app.component.ts')(format='.')
|
+makeExample('testing/ts/app/app.component.ts', '', 'app/app.component.ts')(format='.')
|
||||||
.l-sub-section
|
|
||||||
:marked
|
|
||||||
This component may not seem worth testing but it's instructive to show how to test it.
|
|
||||||
:marked
|
:marked
|
||||||
Unit tests can confirm that the anchors are wired properly without engaging the router.
|
Unit tests can confirm that the anchors are wired properly without engaging the router.
|
||||||
|
See why this is worth doing [below](#why-stubbed-routerlink-tests).
|
||||||
|
|
||||||
a#stub-component
|
#stub-component
|
||||||
:marked
|
:marked
|
||||||
### Stubbing unneeded components
|
### Stubbing unneeded components
|
||||||
|
|
||||||
|
@ -1251,7 +1250,7 @@ a#stub-component
|
||||||
The component stubs are essential.
|
The component stubs are essential.
|
||||||
Without them, the Angular compiler doesn't recognize the `<app-welcome>` and `<router-outlet>` tags
|
Without them, the Angular compiler doesn't recognize the `<app-welcome>` and `<router-outlet>` tags
|
||||||
and throws an error.
|
and throws an error.
|
||||||
a#router-link-stub
|
#router-link-stub
|
||||||
:marked
|
:marked
|
||||||
### Stubbing the _RouterLink_
|
### Stubbing the _RouterLink_
|
||||||
|
|
||||||
|
@ -1263,8 +1262,8 @@ a#router-link-stub
|
||||||
Clicking the anchor should trigger the `onClick` method which sets the telltale `navigatedTo` property.
|
Clicking the anchor should trigger the `onClick` method which sets the telltale `navigatedTo` property.
|
||||||
Tests can inspect that property to confirm the expected _click-to-navigation_ behavior.
|
Tests can inspect that property to confirm the expected _click-to-navigation_ behavior.
|
||||||
|
|
||||||
a#by-directive
|
#by-directive
|
||||||
a#inject-directive
|
#inject-directive
|
||||||
:marked
|
:marked
|
||||||
### _By.directive_ and injected directives
|
### _By.directive_ and injected directives
|
||||||
|
|
||||||
|
@ -1278,7 +1277,7 @@ a#inject-directive
|
||||||
1. You can use the component's dependency injector to get an attached directive because
|
1. You can use the component's dependency injector to get an attached directive because
|
||||||
Angular always adds attached directives to the component's injector.
|
Angular always adds attached directives to the component's injector.
|
||||||
|
|
||||||
a#app-component-tests
|
#app-component-tests
|
||||||
:marked
|
:marked
|
||||||
Here are some tests that leverage this setup:
|
Here are some tests that leverage this setup:
|
||||||
+makeExample('testing/ts/app/app.component.spec.ts', 'tests', 'app/app.component.spec.ts (selected tests)')(format='.')
|
+makeExample('testing/ts/app/app.component.spec.ts', 'tests', 'app/app.component.spec.ts (selected tests)')(format='.')
|
||||||
|
@ -1295,10 +1294,28 @@ a#app-component-tests
|
||||||
This is a skill you may need to test a more sophisticated component, one that changes the display,
|
This is a skill you may need to test a more sophisticated component, one that changes the display,
|
||||||
re-calculates parameters, or re-arranges navigation options when the user clicks the link.
|
re-calculates parameters, or re-arranges navigation options when the user clicks the link.
|
||||||
|
|
||||||
|
#why-stubbed-routerlink-tests
|
||||||
|
:marked
|
||||||
|
### What good are these tests?
|
||||||
|
|
||||||
|
Stubbed `RouterLink` tests can confirm that a component with links and an outlet is setup properly,
|
||||||
|
that the component has the links it should have and
|
||||||
|
that they are all pointing in the expected direction.
|
||||||
|
These tests do not concern whether the app will succeed in navigating to the target component when the user clicks a link.
|
||||||
|
|
||||||
|
Stubbing the RouterLink and RouterOutlet is the best option for such limited testing goals.
|
||||||
|
Relying on the real router would make them brittle.
|
||||||
|
They could fail for reasons unrelated to the component.
|
||||||
|
For example, a navigation guard could prevent an unauthorized user from visiting the `HeroListComponent`.
|
||||||
|
That's not the fault of the `AppComponent` and no change to that component could cure the failed test.
|
||||||
|
|
||||||
|
A _different_ battery of tests can explore whether the application navigates as expected
|
||||||
|
in the presence of conditions that influence guards such as whether the user is authenticated and authorized.
|
||||||
|
A future chapter update will explain how to write such tests with the `RouterTestingModule`.
|
||||||
a(href="#top").to-top Back to top
|
a(href="#top").to-top Back to top
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#shallow-component-test
|
#shallow-component-test
|
||||||
:marked
|
:marked
|
||||||
# "Shallow component tests" with *NO\_ERRORS\_SCHEMA*
|
# "Shallow component tests" with *NO\_ERRORS\_SCHEMA*
|
||||||
|
|
||||||
|
@ -1332,7 +1349,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#attribute-directive
|
#attribute-directive
|
||||||
:marked
|
:marked
|
||||||
# Test an attribute directive
|
# Test an attribute directive
|
||||||
|
|
||||||
|
@ -1392,8 +1409,8 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#isolated-tests
|
#isolated-tests
|
||||||
a#testing-without-atp
|
#testing-without-atp
|
||||||
:marked
|
:marked
|
||||||
# Testing without the Angular Testing Platform
|
# Testing without the Angular Testing Platform
|
||||||
|
|
||||||
|
@ -1423,7 +1440,7 @@ a#testing-without-atp
|
||||||
Write _Angular_ tests to validate the part as it interacts with Angular,
|
Write _Angular_ tests to validate the part as it interacts with Angular,
|
||||||
updates the DOM, and collaborates with the rest of the application.
|
updates the DOM, and collaborates with the rest of the application.
|
||||||
|
|
||||||
a#isolated-service-tests
|
#isolated-service-tests
|
||||||
:marked
|
:marked
|
||||||
## Services
|
## Services
|
||||||
Services are good candidates for isolated unit testing.
|
Services are good candidates for isolated unit testing.
|
||||||
|
@ -1474,7 +1491,7 @@ a#isolated-service-tests
|
||||||
Use the Angular Testing Platform when writing tests that validate how a service interacts with components
|
Use the Angular Testing Platform when writing tests that validate how a service interacts with components
|
||||||
_within the Angular runtime environment_.
|
_within the Angular runtime environment_.
|
||||||
|
|
||||||
a#isolated-pipe-tests
|
#isolated-pipe-tests
|
||||||
:marked
|
:marked
|
||||||
## Pipes
|
## Pipes
|
||||||
Pipes are easy to test without the Angular Testing Platform (ATP).
|
Pipes are easy to test without the Angular Testing Platform (ATP).
|
||||||
|
@ -1500,7 +1517,7 @@ a#isolated-pipe-tests
|
||||||
Consider adding ATP component tests such as this one.
|
Consider adding ATP component tests such as this one.
|
||||||
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'title-case-pipe', 'app/hero/hero-detail.component.spec.ts (pipe test)')
|
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'title-case-pipe', 'app/hero/hero-detail.component.spec.ts (pipe test)')
|
||||||
|
|
||||||
a#isolated-component-tests
|
#isolated-component-tests
|
||||||
:marked
|
:marked
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
|
@ -1537,7 +1554,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#atp-api
|
#atp-api
|
||||||
:marked
|
:marked
|
||||||
# Angular Testing Platform APIs
|
# Angular Testing Platform APIs
|
||||||
|
|
||||||
|
@ -1629,7 +1646,7 @@ table
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#testbed-class-summary
|
#testbed-class-summary
|
||||||
:marked
|
:marked
|
||||||
# _TestBed_ Class Summary
|
# _TestBed_ Class Summary
|
||||||
The `TestBed` class is a principle feature of the _Angular Testing Platform_.
|
The `TestBed` class is a principle feature of the _Angular Testing Platform_.
|
||||||
|
@ -1659,7 +1676,7 @@ code-example(format="." language="javascript").
|
||||||
};
|
};
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
a#testbed-methods
|
#testbed-methods
|
||||||
:marked
|
:marked
|
||||||
The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the`TestBed`.
|
The `TestBed` API consists of static class methods that either update or reference a _global_ instance of the`TestBed`.
|
||||||
|
|
||||||
|
@ -1677,7 +1694,7 @@ table
|
||||||
td
|
td
|
||||||
:marked
|
:marked
|
||||||
The testing shims (`karma-test-shim`, `browser-test-shim`)
|
The testing shims (`karma-test-shim`, `browser-test-shim`)
|
||||||
establish the [initial test environment](#a#testbed-initTestEnvironment) and a default testing module.
|
establish the [initial test environment](##testbed-initTestEnvironment) and a default testing module.
|
||||||
The default testing module is configured with basic declaratives and some Angular service substitutes (e.g. `DebugDomRender`)
|
The default testing module is configured with basic declaratives and some Angular service substitutes (e.g. `DebugDomRender`)
|
||||||
that every tester needs.
|
that every tester needs.
|
||||||
|
|
||||||
|
@ -1771,7 +1788,7 @@ table
|
||||||
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.
|
A few of the `TestBed` instance methods are not covered by static `TestBed` _class_ methods.
|
||||||
These are rarely needed.
|
These are rarely needed.
|
||||||
|
|
||||||
a#component-fixture-api-summary
|
#component-fixture-api-summary
|
||||||
:marked
|
:marked
|
||||||
## The _ComponentFixture_
|
## The _ComponentFixture_
|
||||||
|
|
||||||
|
@ -1782,7 +1799,7 @@ a#component-fixture-api-summary
|
||||||
The `ComponentFixture` properties and methods provide access to the component,
|
The `ComponentFixture` properties and methods provide access to the component,
|
||||||
its DOM representation, and aspects of its Angular environment.
|
its DOM representation, and aspects of its Angular environment.
|
||||||
|
|
||||||
a#component-fixture-properties
|
#component-fixture-properties
|
||||||
:marked
|
:marked
|
||||||
### _ComponentFixture_ properties
|
### _ComponentFixture_ properties
|
||||||
|
|
||||||
|
@ -1820,7 +1837,7 @@ table
|
||||||
component that has the `ChangeDetectionStrategy.OnPush`
|
component that has the `ChangeDetectionStrategy.OnPush`
|
||||||
or the component's change detection is under your programmatic control.
|
or the component's change detection is under your programmatic control.
|
||||||
|
|
||||||
a#component-fixture-methods
|
#component-fixture-methods
|
||||||
:marked
|
:marked
|
||||||
### _ComponentFixture_ methods
|
### _ComponentFixture_ methods
|
||||||
|
|
||||||
|
@ -1887,7 +1904,7 @@ table
|
||||||
:marked
|
:marked
|
||||||
Trigger component destruction.
|
Trigger component destruction.
|
||||||
|
|
||||||
a#debug-element-details
|
#debug-element-details
|
||||||
:marked
|
:marked
|
||||||
### _DebugElement_
|
### _DebugElement_
|
||||||
|
|
||||||
|
@ -2003,7 +2020,7 @@ table
|
||||||
Dictionary of objects associated with template local variables (e.g. `#foo`),
|
Dictionary of objects associated with template local variables (e.g. `#foo`),
|
||||||
keyed by the local variable name.
|
keyed by the local variable name.
|
||||||
|
|
||||||
a#query-predicate
|
#query-predicate
|
||||||
:marked
|
:marked
|
||||||
The `DebugElement.query(predicate)` and `DebugElement.queryAll(predicate)` methods take a
|
The `DebugElement.query(predicate)` and `DebugElement.queryAll(predicate)` methods take a
|
||||||
predicate that filters the source element's subtree for matching `DebugElement`.
|
predicate that filters the source element's subtree for matching `DebugElement`.
|
||||||
|
@ -2020,7 +2037,7 @@ a#query-predicate
|
||||||
|
|
||||||
+makeExample('testing/ts/app/hero/hero-list.component.spec.ts', 'by', 'app/hero/hero-list.component.spec.ts')(format=".")
|
+makeExample('testing/ts/app/hero/hero-list.component.spec.ts', 'by', 'app/hero/hero-list.component.spec.ts')(format=".")
|
||||||
|
|
||||||
a#renderer-tests
|
#renderer-tests
|
||||||
:marked
|
:marked
|
||||||
Many custom application directives inject the `Renderer` and call one of its `set...` methods.
|
Many custom application directives inject the `Renderer` and call one of its `set...` methods.
|
||||||
|
|
||||||
|
@ -2068,7 +2085,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l.hr
|
.l.hr
|
||||||
|
|
||||||
a#faq
|
#faq
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## FAQ: Frequently Asked Questions
|
## FAQ: Frequently Asked Questions
|
||||||
|
@ -2106,7 +2123,7 @@ a(href="#top").to-top Back to top
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#q-spec-file-location
|
#q-spec-file-location
|
||||||
:marked
|
:marked
|
||||||
### Why put specs next to the things they test?
|
### Why put specs next to the things they test?
|
||||||
|
|
||||||
|
@ -2120,7 +2137,7 @@ a#q-spec-file-location
|
||||||
|
|
||||||
.l-hr
|
.l-hr
|
||||||
|
|
||||||
a#q-specs-in-test-folder
|
#q-specs-in-test-folder
|
||||||
:marked
|
:marked
|
||||||
### When would I put specs in a test folder?
|
### When would I put specs in a test folder?
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue