style: fix whitespace and indentation in the testing guide (#21669)

PR Close #21669
This commit is contained in:
Igor Minar 2018-08-07 15:52:48 -07:00 committed by Kara Erickson
parent 24f1dd3b81
commit a16de8f842
2 changed files with 373 additions and 371 deletions

View File

@ -6,8 +6,8 @@ This guide offers tips and techniques for unit and integration testing Angular a
The guide presents tests of a sample CLI application that is much like the [_Tour of Heroes_ tutorial](tutorial). The guide presents tests of a sample CLI application that is much like the [_Tour of Heroes_ tutorial](tutorial).
The sample application and all tests in this guide are available for inspection and experimentation: The sample application and all tests in this guide are available for inspection and experimentation:
* <live-example embedded-style>Sample app</live-example> - <live-example embedded-style>Sample app</live-example>
* <live-example stackblitz="specs">Tests</live-example> - <live-example stackblitz="specs">Tests</live-example>
<hr> <hr>
@ -403,11 +403,11 @@ respond to user input and gestures, or integrate with its parent and child compo
None of the _class-only_ tests above can answer key questions about how the None of the _class-only_ tests above can answer key questions about how the
components actually behave on screen. components actually behave on screen.
* Is `Lightswitch.clicked()` bound to anything such that the user can invoke it? - Is `Lightswitch.clicked()` bound to anything such that the user can invoke it?
* Is the `Lightswitch.message` displayed? - Is the `Lightswitch.message` displayed?
* Can the user actually select the hero displayed by `DashboardHeroComponent`? - Can the user actually select the hero displayed by `DashboardHeroComponent`?
* Is the hero name displayed as expected (i.e, in uppercase)? - Is the hero name displayed as expected (i.e, in uppercase)?
* Is the welcome message displayed by the template of `WelcomeComponent`? - Is the welcome message displayed by the template of `WelcomeComponent`?
These may not be troubling questions for the simple components illustrated above. These may not be troubling questions for the simple components illustrated above.
But many components have complex interactions with the DOM elements But many components have complex interactions with the DOM elements
@ -645,10 +645,10 @@ The following example re-implements the previous test with
Some noteworthy observations: Some noteworthy observations:
* The `By.css()` static method selects `DebugElement` nodes - The `By.css()` static method selects `DebugElement` nodes
with a [standard CSS selector](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors "CSS selectors"). with a [standard CSS selector](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/Selectors 'CSS selectors').
* The query returns a `DebugElement` for the paragraph. - The query returns a `DebugElement` for the paragraph.
* You must unwrap that result to get the paragraph element. - You must unwrap that result to get the paragraph element.
When you're filtering by CSS selector and only testing properties of a browser's _native element_, the `By.css` approach may be overkill. When you're filtering by CSS selector and only testing properties of a browser's _native element_, the `By.css` approach may be overkill.
@ -706,6 +706,7 @@ Your instinct is to write a test that immediately inspects the `<h1>` like this:
</code-example> </code-example>
_That test fails_ with the message: _That test fails_ with the message:
```javascript ```javascript
expected '' to contain 'Test Tour of Heroes'. expected '' to contain 'Test Tour of Heroes'.
``` ```
@ -739,7 +740,6 @@ the component _before Angular initiates data binding and calls [lifecycle hooks]
Here's another test that changes the component's `title` property _before_ calling `fixture.detectChanges()`. Here's another test that changes the component's `title` property _before_ calling `fixture.detectChanges()`.
<code-example <code-example
path="testing/src/app/banner/banner.component.spec.ts" path="testing/src/app/banner/banner.component.spec.ts"
region="after-change"> region="after-change">
@ -1051,6 +1051,7 @@ The test must wait at least one full turn of the JavaScript engine before the
value becomes available. The test must become _asynchronous_. value becomes available. The test must become _asynchronous_.
{@a fake-async} {@a fake-async}
#### Async test with _fakeAsync()_ #### Async test with _fakeAsync()_
The following test confirms the expected behavior when the service returns an `ErrorObservable`. The following test confirms the expected behavior when the service returns an `ErrorObservable`.
@ -1061,6 +1062,7 @@ The following test confirms the expected behavior when the service returns an `E
</code-example> </code-example>
Note that the `it()` function receives an argument of the following form. Note that the `it()` function receives an argument of the following form.
```javascript ```javascript
fakeAsync(() => { /* test body */ })` fakeAsync(() => { /* test body */ })`
``` ```
@ -1261,7 +1263,6 @@ But it is occasionally necessary.
For example, you can't call `async` or `fakeAsync` when testing For example, you can't call `async` or `fakeAsync` when testing
code that involves the `intervalTimer()` or the RxJS `delay()` operator. code that involves the `intervalTimer()` or the RxJS `delay()` operator.
Here are two mover versions of the previous test, written with `done()`. Here are two mover versions of the previous test, written with `done()`.
The first one subscribes to the `Observable` exposed to the template by the component's `quote` property. The first one subscribes to the `Observable` exposed to the template by the component's `quote` property.
@ -1393,7 +1394,6 @@ A _hot_ observable is already producing values _before_ you subscribe to it.
The [_Router.events_](api/router/Router#events) observable, The [_Router.events_](api/router/Router#events) observable,
which reports router activity, is a _hot_ observable. which reports router activity, is a _hot_ observable.
RxJS marble testing is a rich subject, beyond the scope of this guide. RxJS marble testing is a rich subject, beyond the scope of this guide.
Learn about it on the web, starting with the Learn about it on the web, starting with the
[official documentation](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md). [official documentation](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md).
@ -1439,9 +1439,9 @@ Here's the component's full definition:
While testing a component this simple has little intrinsic value, it's worth knowing how. While testing a component this simple has little intrinsic value, it's worth knowing how.
You can use one of these approaches: You can use one of these approaches:
* Test it as used by `DashboardComponent`. - Test it as used by `DashboardComponent`.
* Test it as a stand-alone component. - Test it as a stand-alone component.
* Test it as used by a substitute for `DashboardComponent`. - Test it as used by a substitute for `DashboardComponent`.
A quick look at the `DashboardComponent` constructor discourages the first approach: A quick look at the `DashboardComponent` constructor discourages the first approach:
@ -1561,6 +1561,7 @@ which is perfectly fine for _this component_.
</code-example> </code-example>
{@a click-helper} {@a click-helper}
#### _click()_ helper #### _click()_ helper
Clicking a button, an anchor, or an arbitrary HTML element is a common test task. Clicking a button, an anchor, or an arbitrary HTML element is a common test task.
@ -1756,10 +1757,11 @@ by manipulating the `ActivatedRoute` injected into the component's constructor.
You know how to spy on the `Router` and a data service. You know how to spy on the `Router` and a data service.
You'll take a different approach with `ActivatedRoute` because You'll take a different approach with `ActivatedRoute` because
* `paramMap` returns an `Observable` that can emit more than one value
during a test. - `paramMap` returns an `Observable` that can emit more than one value
* You need the router helper function, `convertToParamMap()`, to create a `ParamMap`. during a test.
* Other _routed components_ tests need a test double for `ActivatedRoute`. - You need the router helper function, `convertToParamMap()`, to create a `ParamMap`.
- Other _routed components_ tests need a test double for `ActivatedRoute`.
These differences argue for a re-usable stub class. These differences argue for a re-usable stub class.
@ -1778,8 +1780,8 @@ This sample puts `ActivatedRouteStub` in `testing/activated-route-stub.ts`.
<div class="alert is-helpful"> <div class="alert is-helpful">
Consider writing a more capable version of this stub class with Consider writing a more capable version of this stub class with
the [_marble testing library_](#marble-testing). the [_marble testing library_](#marble-testing).
</div> </div>
@ -1895,7 +1897,7 @@ The rest are stubs.
{@a no-errors-schema} {@a no-errors-schema}
#### *NO\_ERRORS\_SCHEMA* #### _NO_ERRORS_SCHEMA_
In the second approach, add `NO_ERRORS_SCHEMA` to the `TestBed.schemas` metadata. In the second approach, add `NO_ERRORS_SCHEMA` to the `TestBed.schemas` metadata.
@ -2077,11 +2079,11 @@ But there's plenty of template complexity even in this simple form.
Tests that exercise the component need ... Tests that exercise the component need ...
* to wait until a hero arrives before elements appear in the DOM. - to wait until a hero arrives before elements appear in the DOM.
* a reference to the title text. - a reference to the title text.
* a reference to the name input box to inspect and set it. - a reference to the name input box to inspect and set it.
* references to the two buttons so they can click them. - references to the two buttons so they can click them.
* spies for some of the component and router methods. - spies for some of the component and router methods.
Even a small form such as this one can produce a mess of tortured conditional setup and CSS element selection. Even a small form such as this one can produce a mess of tortured conditional setup and CSS element selection.
@ -2293,10 +2295,10 @@ which means you can also specify `providers` and `imports`.
The `HeroDetailComponent` requires a lot of help despite its small size and simple construction. The `HeroDetailComponent` requires a lot of help despite its small size and simple construction.
In addition to the support it receives from the default testing module `CommonModule`, it needs: In addition to the support it receives from the default testing module `CommonModule`, it needs:
* `NgModel` and friends in the `FormsModule` to enable two-way data binding. - `NgModel` and friends in the `FormsModule` to enable two-way data binding.
* The `TitleCasePipe` from the `shared` folder. - The `TitleCasePipe` from the `shared` folder.
* Router services (which these tests are stubbing). - Router services (which these tests are stubbing).
* Hero data access services (also stubbed). - Hero data access services (also stubbed).
One approach is to configure the testing module from the individual pieces as in this example: One approach is to configure the testing module from the individual pieces as in this example:
@ -2523,20 +2525,20 @@ Here are some tests of this component:
A few techniques are noteworthy: A few techniques are noteworthy:
* The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_. - The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.
* The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-class</a> - The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-class</a>
in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive. in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.
`By.css('*:not([highlight])')` finds _any_ element that does not have the directive. `By.css('*:not([highlight])')` finds _any_ element that does not have the directive.
* `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction. - `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.
But feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction. But feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction.
* Angular adds a directive to the injector of the element to which it is applied. - Angular adds a directive to the injector of the element to which it is applied.
The test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance The test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance
and its `defaultColor`. and its `defaultColor`.
* `DebugElement.properties` affords access to the artificial custom property that is set by the directive. - `DebugElement.properties` affords access to the artificial custom property that is set by the directive.
<hr> <hr>
@ -2579,13 +2581,13 @@ Consider adding component tests such as this one:
Debug specs in the browser in the same way that you debug an application. Debug specs in the browser in the same way that you debug an application.
1. Reveal the karma browser window (hidden earlier). 1. Reveal the karma browser window (hidden earlier).
1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests. 1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.
1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on windows; `Command-Option-I` in OSX). 1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on windows; `Command-Option-I` in OSX).
1. Pick the "sources" section. 1. Pick the "sources" section.
1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file). 1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file).
1. Set a breakpoint in the test. 1. Set a breakpoint in the test.
1. Refresh the browser, and it stops at the breakpoint. 1. Refresh the browser, and it stops at the breakpoint.
<figure> <figure>
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging"> <img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
@ -2958,7 +2960,6 @@ Here are the most important static methods, in order of likely utility.
</tr> </tr>
</table </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.
@ -3382,9 +3383,9 @@ The following example finds all `DebugElements` with a reference to a template l
The Angular `By` class has three static methods for common predicates: The Angular `By` class has three static methods for common predicates:
* `By.all` - return all elements. - `By.all` - return all elements.
* `By.css(selector)` - return elements with matching CSS selectors. - `By.css(selector)` - return elements with matching CSS selectors.
* `By.directive(directive)` - return elements that Angular matched to an instance of the directive class. - `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" title="app/hero/hero-list.component.spec.ts" linenums="false"></code-example> <code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" title="app/hero/hero-list.component.spec.ts" linenums="false"></code-example>
@ -3401,11 +3402,11 @@ The Angular `By` class has three static methods for common predicates:
It's a good idea to put unit test spec files in the same folder It's a good idea to put unit test spec files in the same folder
as the application source code files that they test: as the application source code files that they test:
* Such tests are easy to find. - Such tests are easy to find.
* You see at a glance if a part of your application lacks tests. - You see at a glance if a part of your application lacks tests.
* Nearby tests can reveal how a part works in context. - Nearby tests can reveal how a part works in context.
* When you move the source (inevitable), you remember to move the test. - When you move the source (inevitable), you remember to move the test.
* When you rename the source file (inevitable), you remember to rename the test file. - When you rename the source file (inevitable), you remember to rename the test file.
<hr> <hr>
@ -3424,6 +3425,7 @@ Of course specs that test the test helpers belong in the `test` folder,
next to their corresponding helper files. next to their corresponding helper files.
{@a q-e2e} {@a q-e2e}
#### Why not rely on E2E tests of DOM integration? #### Why not rely on E2E tests of DOM integration?
The component DOM tests described in this guide often require extensive setup and The component DOM tests described in this guide often require extensive setup and