diff --git a/public/docs/ts/latest/guide/testing.jade b/public/docs/ts/latest/guide/testing.jade
index 03b27987e3..1640f2df30 100644
--- a/public/docs/ts/latest/guide/testing.jade
+++ b/public/docs/ts/latest/guide/testing.jade
@@ -2050,7 +2050,7 @@ a(href="#top").to-top 回到顶部
路由器将`:id`令牌的值推送到`ActivatedRoute.params`**可观察**属性里,
Angular注入`ActivatedRoute`到`HeroDetailComponent`中,
- 然后组件提取`id`,这样它就可以通过`HeroDetailServide`获取相应的英雄。
+ 然后组件提取`id`,这样它就可以通过`HeroDetailService`获取相应的英雄。
下面是`HeroDetailComponent`的构造函数:
+makeExample('testing/ts/app/hero/hero-detail.component.ts', 'ctor', 'app/hero/hero-detail.component.ts (constructor)')(format='.')
:marked
@@ -2149,29 +2149,48 @@ a(href="#top").to-top 回到顶部
#observable-tests
:marked
### _Observable_ tests
+
+ ### **可观察对象**测试
+
Here's a test demonstrating the component's behavior when the observed `id` refers to an existing hero:
+
+ 下面的测试是演示组件在被观察的`id`指向现有英雄时的行为:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'route-good-id', 'app/hero/hero-detail.component.spec.ts (existing id)')(format='.')
.l-sub-section
:marked
The `createComponent` method and `page` object are discussed [in the next section](#page-object).
Rely on your intuition for now.
+
+ 将在[下一节](#page-object)解释`createComponent`方法和`page`对象,现在暂时跟随自己的直觉。
:marked
When the `id` cannot be found, the component should re-route to the `HeroListComponent`.
The test suite setup provided the same `RouterStub` [described above](#routed-component) which spies on the router without actually navigating.
This test supplies a "bad" id and expects the component to try to navigate.
+
+ 当无法找到`id`时,组件应该重新导航到`HeroListComponent`。
+ 该测试套件配置提供了与[上面描述](#routed-component)的`RouterStub`一样,它在不实际导航的情况下刺探路由器。
+ 该测试提供了一个“坏”的id,期望组件尝试导航。
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'route-bad-id', 'app/hero/hero-detail.component.spec.ts (bad id)')(format='.')
:marked
:marked
While this app doesn't have a route to the `HeroDetailComponent` that omits the `id` parameter, it might add such a route someday.
The component should do something reasonable when there is no `id`.
+ 虽然本应用没有导航到`HeroDetailComponent`的缺少`id`参数的路由,将来它可能会添加这样一个路由。
+ 当没有`id`时,该组件应该作出什么合理的反应。
+
In this implementation, the component should create and display a new hero.
New heroes have `id=0` and a blank `name`. This test confirms that the component behaves as expected:
+
+ 在本例中,组件应该创建和显示一个新英雄。
+ 新英雄的id为零,`name`为空。本测试确认组件是按照预期的这样做的:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'route-no-id', 'app/hero/hero-detail.component.spec.ts (no id)')(format='.')
:marked
.callout.is-helpful
:marked
Inspect and download _all_ of the chapter's application test code with this live example.
+
+ 到在线例子查看和下载**所有**本章应用测试代码。
.l-hr
@@ -2179,132 +2198,241 @@ a(href="#top").to-top 回到顶部
:marked
# Use a _page_ object to simplify setup
+ # 使用一个**page**对象来简化配置
+
The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.
+
+ `HeroDetailComponent`是一个带有标题、两个英雄字段和两个按钮的简单视图。
figure.image-display
img(src='/resources/images/devguide/testing/hero-detail.component.png' alt="HeroDetailComponent in action")
:marked
But there's already plenty of template complexity.
+
+ 但是它已经有很多模板的复杂性。
+makeExample('testing/ts/app/hero/hero-detail.component.html', '', 'app/hero/hero-detail.component.html')(format='.')
:marked
To fully exercise the component, the test needs ...
+
+ 要彻底测试该组件,测试需要:
+
* to wait until a `hero` arrives before `*ngIf` allows any element in DOM
+
+ * 在`*ngIf`允许元素进入DOM之前,等待`hero`的到来
+
* element references for the title name span and name input-box to inspect their values
+
+ * 标题名字span和名字输入框元素的引用,用来检查它们的值
+
* two button references to click
+
+ * 两个按钮的引用,用来点击
+
* spies on services and component methods
+ * spy服务和组件的方法
+
Even a small form such as this one can produce a mess of tortured conditional setup and CSS element selection.
+ 即使是像这样一个很小的表单,也能产生令人疯狂的错综复杂的条件设置和CSS元素选择。
+
Tame the madness with a `Page` class that simplifies access to component properties and encapsulates the logic that sets them.
Here's the `Page` class for the `hero-detail.component.spec.ts`
+
+ 通过简化组件属性的访问和封装设置属性的逻辑,`Page`类可以轻松解决这个令人疯狂的难题。
+ 下面是为`hero-detail.component.spec.ts`准备的`page`类:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'page', 'app/hero/hero-detail.component.spec.ts (Page)')(format='.')
:marked
Now the important hooks for component manipulation and inspection are neatly organized and accessible from an instance of `Page`.
+ 现在,用来操作和检查组件的重要钩子都被井然有序的组织起来了,可以通过`page`实例来使用它们。
+
A `createComponent` method creates a `page` and fills in the blanks once the `hero` arrives.
+
+ `createComponent`方法创建一个`page`,在`hero`到来时,自动填补空白。
+
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'create-component', 'app/hero/hero-detail.component.spec.ts (createComponent)')(format='.')
:marked
The [observable tests](#observable-tests) in the previous section demonstrate how `createComponent` and `page`
keep the tests short and _on message_.
There are no distractions: no waiting for promises to resolve and no searching the DOM for element values to compare.
Here are a few more `HeroDetailComponent` tests to drive the point home.
+
+ 上一节的[可观察对象测试](#observable-tests)展示了`createComponent`和`page`如何让测试简短和即时的。
+ 没有任何干扰:无需等待承诺的解析,也没有搜索DOM元素值进行比较。
+ 这里是一些更多的`HeroDetailComponent`测试来进一步展示这一点。
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'selected-tests', 'app/hero/hero-detail.component.spec.ts (selected tests)')(format='.')
a(href="#top").to-top Back to top
+a(href="#top").to-top 回到顶部
.l-hr
#import-module
:marked
# Setup with module imports
+
+ # 模块导入imports的配置
+
Earlier component tests configured the testing module with a few `declarations` like this:
+
+ 此前的组件测试使用了一些`declarations`来配置模块,就像这样:
+makeExample('testing/ts/app/dashboard/dashboard-hero.component.spec.ts', 'compile-components', 'app/dashboard/dashboard-hero.component.spec.ts (config)')(format='.')
:marked
The `DashboardComponent` is simple. It needs no help.
But more complex components often depend on other components, directives, pipes, and providers
and these must be added to the testing module too.
+ `DashbaordComponent`非常简单。它不需要帮助。
+ 但是更加复杂的组件通常依赖其它组件、指令、管道和提供商,
+ 所以这些必须也被添加到测试模块中。
+
Fortunately, the `TestBed.configureTestingModule` parameter parallels
the metadata passed to the `@NgModule` decorator
- which means you can also specify `providers` and `imports.
+ which means you can also specify `providers` and `imports`.
+
+ 幸运的是,`TestBed.configureTestingModule`参数与传入`@NgModule`装饰器的元数据一样,也就是所你也可以指定`providers`和`imports`.
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:
+
+ 虽然`HeroDetailComponent`很小,结构也很简单,但是它需要很多帮助。
+ 除了从默认测试模块`CommonModule`中获得的支持,它还需要:
+
* `NgModel` and friends in the `FormsModule` enable two-way data binding
+
+ * `FormsModule`里的`NgModel`和其它,来进行双向数据绑定
+
* The `TitleCasePipe` from the `shared` folder
+
+ * `shared`目录里的`TitleCasePipe`
+
* Router services (which these tests are stubbing)
+
+ * 一些路由器服务(测试将stub伪造它们)
+
* Hero data access services (also stubbed)
+ * 英雄数据访问服务(同样被stub伪造了)
+
One approach is to configure the testing module from the individual pieces as in this example:
+
+ 一种方法是在测试模块中一一配置,就像这样:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'setup-forms-module', 'app/hero/hero-detail.component.spec.ts (FormsModule setup)')(format='.')
:marked
Because many app components need the `FormsModule` and the `TitleCasePipe`, the developer created
a `SharedModule` to combine these and other frequently requested parts.
The test configuration can use the `SharedModule` too as seen in this alternative setup:
+
+ 因为许多应用组件需要`FormsModule`和`TitleCasePipe`,所以开发者创建了一个`SharedModule`来合并它们和一些频繁需要的部件。
+ 测试配置也可以使用`SharedModule`,请看下面另一种配置:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'setup-shared-module', 'app/hero/hero-detail.component.spec.ts (SharedModule setup)')(format='.')
:marked
It's a bit tighter and smaller, with fewer import statements (not shown).
+ 它的导入声明少一些(未显示),稍微干净一些,小一些。
+
#feature-module-import
:marked
### Import the feature module
+
+ ### 导入特征模块
+
The `HeroDetailComponent` is part of the `HeroModule` [Feature Module](ngmodule.html#feature-modules) that aggregates more of the interdependent pieces
including the `SharedModule`.
Try a test configuration that imports the `HeroModule` like this one:
+
+ `HeroDetailComponent`是`HeroModule`[特征模块](ngmodule.html#feature-modules)的一部分,它组合了更多互相依赖的部件,包括`SharedModule`。
+ 试试下面这个导入`HeroModule`的测试配置:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'setup-hero-module', 'app/hero/hero-detail.component.spec.ts (HeroModule setup)')(format='.')
:marked
That's _really_ crisp. Only the _test doubles_ in the `providers` remain. Even the `HeroDetailComponent` declaration is gone.
+
+ 这样特别清爽。只有`providers`里面的测试复制品被保留。连`HeroDetailComponent`声明都消失了。
.l-sub-section
:marked
In fact, if you try to declare it, Angular throws an error because
`HeroDetailComponent` is declared in both the `HeroModule` and the `DynamicTestModule` (the testing module).
+ 事实上,如果里试图声明它,Angular会抛出一个错误,因为`HeroDetailComponent`已经在`HeroModule`和测试模块的`DynamicTestModule`中声明。
+
.alert.is-helpful
:marked
Importing the component's feature module is often the easiest way to configure the tests,
especially when the feature module is small and mostly self-contained ... as feature modules should be.
+
+ 导入组件的特征模块通常是最简单的配置测试的方法,
+ 尤其是当特征模块很小而且几乎只包含时...特征模块应该如此。
:marked
a(href="#top").to-top Back to top
+a(href="#top").to-top 回到顶部
.l-hr
#component-override
:marked
# Override component providers
+ # 替换组件提供商
+
The `HeroDetailComponent` provides its own `HeroDetailService`.
+
+ `HeroDetailComponent`提供自己的`HeroDetailService`服务。
+makeExample('testing/ts/app/hero/hero-detail.component.ts', 'prototype', 'app/hero/hero-detail.component.ts (prototype)')(format='.')
:marked
It's not possible to stub the component's `HeroDetailService` in the `providers` of the `TestBed.configureTestingModule`.
Those are providers for the _testing module_, not the component. They prepare the dependency injector at the _fixture level_.
+ 在`TestBed.configureTestingModule`的`providers`中stub伪造组件的`HeroDetailService`是不可行的。
+ 这些是**测试模块**的提供商,而非组件的。它们在**fixture级别**准备依赖注入器。
+
Angular creates the component with its _own_ injector which is a _child_ of the fixture injector.
It registers the component's providers (the `HeroDetailService` in this case) with the child injector.
A test cannot get to child injector services from the fixture injector.
And `TestBed.configureTestingModule` can't configure them either.
+ Angular创建一个组件时,该组件有自己的注入器,它是fixture注入器的子级。
+ Angular使用这个子级注入器来注册组件的提供商(也就是`HeroDetailService`)。
+ 测试无法从fixture的注入器获取这个子级注入器。
+ 而且`TestBed.configureTestingModule`也无法配置它们。
+
Angular has been creating new instances of the real `HeroDetailService` all along!
+ Angular始终都在创建真实`HeroDetailService`的实例。
+
.l-sub-section
:marked
These tests could fail or timeout if the `HeroDetailService` made its own XHR calls to a remote server.
There might not be a remote server to call.
+ 如果`HeroDetailService`向一个远程服务器发出自己的XHR请求,这些测试可能会失败或者超时。
+ 这个远程服务器可能根本不存在。
+
Fortunately, the `HeroDetailService` delegates responsibility for remote data access to an injected `HeroService`.
+ 幸运的是,`HeroDetailServ`将远程数据访问的责任交给了注入进来的`HeroService`。
+
+makeExample('testing/ts/app/hero/hero-detail.service.ts', 'prototype', 'app/hero/hero-detail.service.ts (prototype)')(format='.')
:marked
The [previous test configuration](#feature-module-import) replaces the real `HeroService` with a `FakeHeroService`
that intercepts server requests and fakes their responses.
+ [之前的测试配置](#feature-module-import)将真实的`HeroService`替换为`FakeHeroService`,拦截了服务起请求,伪造了它们的响应。
+
:marked
What if you aren't so lucky. What if faking the `HeroService` is hard?
What if `HeroDetailService` makes its own server requests?
+
+ 如果我们没有这么幸运怎么办?如果伪造`HeroService`很难怎么办?如果`HeroDetailService`自己发出服务器请求怎么办?
The `TestBed.overrideComponent` method can replace the component's `providers` with easy-to-manage _test doubles_
as seen in the following setup variation:
+
+ `TestBed.overrideComponent`方法可以将组件的`providers`替换为容易管理的**测试复制品**,参见下面的设置变化:
+makeExample('testing/ts/app/hero/hero-detail.component.spec.ts', 'setup-override', 'app/hero/hero-detail.component.spec.ts (Override setup)')(format='.')
:marked
Notice that `TestBed.configureTestingModule` no longer provides a (fake) `HeroService` because it's [not needed](#stub-hero-detail-service).
+ 注意,`TestBed.configureTestingModule`不再提供一个(伪造)`HeroService`,因为它是[没必要的](#stub-hero-detail-service)
+
#override-component-method
:marked
### The _overrideComponent_ method