Angular2 - 在组件中测试 ngOninit
Posted
技术标签:
【中文标题】Angular2 - 在组件中测试 ngOninit【英文标题】:Angular2 - Testing ngOninit in Components 【发布时间】:2016-08-09 06:37:05 【问题描述】:我有一个包含以下代码的列表组件:
///<reference path="../../node_modules/angular2/typings/browser.d.ts"/>
import Component, OnInit from 'angular2/core';
import ROUTER_DIRECTIVES from 'angular2/router';
import Employee from '../models/employee';
import EmployeeListServiceComponent from '../services/employee-list-service.component';
@Component(
selector: 'employee-list',
template: `
<ul class="employees">
<li *ngFor="#employee of employees">
<a [routerLink]="['EmployeeDetail', id: employee.id]">
<span class="badge">employee.id</span>
employee.name
</a>
</li>
</ul>
`,
directives: [ROUTER_DIRECTIVES],
providers: [EmployeeListServiceComponent]
)
export class EmployeeListComponent implements OnInit
public employees: Employee[];
public errorMessage: string;
constructor(
private _listingService: EmployeeListServiceComponent
)
ngOnInit()
this._listingService.getEmployees().subscribe(
employees => this.employees = employees,
error => this.errorMessage = <any>error
);
我希望为ngOninit
钩子编写单元测试。我写了以下测试:
/// <reference path="../../typings/main/ambient/jasmine/jasmine.d.ts" />
import
it,
describe,
expect,
TestComponentBuilder,
injectAsync,
setBaseTestProviders,
beforeEachProviders,
from "angular2/testing";
import Component, provide, ApplicationRef, OnInit from "angular2/core";
import
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
from "angular2/platform/testing/browser";
import
ROUTER_DIRECTIVES,
ROUTER_PROVIDERS,
ROUTER_PRIMARY_COMPONENT,
APP_BASE_HREF
from 'angular2/router';
import XHRBackend, HTTP_PROVIDERS from "angular2/http";
import MockApplicationRef from 'angular2/src/mock/mock_application_ref';
import MockBackend from "angular2/src/http/backends/mock_backend";
import Observable from 'rxjs/Rx';
import 'rxjs/Rx';
import Employee from '../models/employee';
import EmployeeListComponent from './list.component';
import EmployeeListServiceComponent from '../services/employee-list-service.component';
class MockEmployeeListServiceComponent
getEmployees ()
return Observable.of([
"id": 1,
"name": "Abhinav Mishra"
]);
@Component(
template: '<employee-list></employee-list>',
directives: [EmployeeListComponent],
providers: [MockEmployeeListServiceComponent]
)
class TestMyList
describe('Employee List Tests', () =>
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS);
beforeEachProviders(() =>
return [
ROUTER_DIRECTIVES,
ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(EmployeeListServiceComponent, useClass: MockEmployeeListServiceComponent),
provide(XHRBackend, useClass: MockBackend),
provide(APP_BASE_HREF, useValue: '/'),
provide(ROUTER_PRIMARY_COMPONENT, useValue: EmployeeListComponent),
provide(ApplicationRef, useClass: MockApplicationRef)
]
);
it('Should be true',
injectAsync([TestComponentBuilder], (tcb) =>
return tcb
.createAsync(TestMyList)
.then((fixture) =>
fixture.detectChanges();
var compiled = fixture.debugElement.nativeElement;
console.log(compiled.innerhtml);
expect(true).toBe(true);
);
)
);
);
但是,console.log
在测试中的输出是一个空的ul
标签如下:
'<employee-list>
<ul class="employees">
<!--template bindings=-->
</ul>
</employee-list>'
谁能建议我为组件钩子编写单元测试的正确方法?
解决方案
模拟injectAsync
块中的http请求如下:
backend.connections.subscribe(
(connection:MockConnection) =>
var options = new ResponseOptions(
body: [
"id": 1,
"name": "Abhinav Mishra"
]
);
var response = new Response(options);
connection.mockRespond(response);
);
但是现在我收到另一个错误如下:
Failed: EXCEPTION: Component "EmployeeListComponent" has no route config. in [['EmployeeDetail', id: employee.id] in EmployeeListComponent@3:7]
ORIGINAL EXCEPTION: Component "EmployeeListComponent" has no route config.
ORIGINAL STACKTRACE:
Error: Component "EmployeeListComponent" has no route config.
【问题讨论】:
【参考方案1】:如果您在 ngOnInit()
中调用异步代码,则不能假设在执行 console.log(...)
时它已完成。 this.employees
仅在您传递给 subscribe(...)
的回调在响应到达后被调用时设置。
如果您使用MockBackend,您可以控制响应,并且在响应通过后您必须再次运行fixture.detectChanges()
以使组件使用更新的数据重新渲染,然后您可以阅读innerHTML
并期待它包含呈现的内容。
【讨论】:
您的解决方案有效。但现在我收到以下错误。你能建议一个解决方法吗?Failed: EXCEPTION: Component "EmployeeListComponent" has no route config. in [['EmployeeDetail', id: employee.id] in EmployeeListComponent@3:7] ORIGINAL EXCEPTION: Component "EmployeeListComponent" has no route config.
也许***.com/questions/35011972/…
仍然遇到同样的错误。你能在这里添加一个示例代码吗?以上是关于Angular2 - 在组件中测试 ngOninit的主要内容,如果未能解决你的问题,请参考以下文章
测试使用 setInterval 或 setTimeout 的 Angular2 组件