在 Angular 2 ngOnInit 中测试承诺 [英] Testing promise in Angular 2 ngOnInit
问题描述
我有一个 Angular 2 组件,我正在尝试对其进行测试,但我遇到了问题,因为数据是在 ngOnInit
函数中设置的,因此在单元测试中无法立即使用.
I have an Angular 2 component I am trying to put under test, but I am having trouble because the data is set in the ngOnInit
function, so is not immediately available in the unit test.
用户视图.component.ts:
user-view.component.ts:
import {Component, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {User} from './user';
import {UserService} from './user.service';
@Component({
selector: 'user-view',
templateUrl: './components/users/view.html'
})
export class UserViewComponent implements OnInit {
public user: User;
constructor(
private _routeParams: RouteParams,
private _userService: UserService
) {}
ngOnInit() {
const id: number = parseInt(this._routeParams.get('id'));
this._userService
.getUser(id)
.then(user => {
console.info(user);
this.user = user;
});
}
}
user.service.ts:
user.service.ts:
import {Injectable} from 'angular2/core';
// mock-users is a static JS array
import {users} from './mock-users';
import {User} from './user';
@Injectable()
export class UserService {
getUsers() : Promise<User[]> {
return Promise.resolve(users);
}
getUser(id: number) : Promise<User> {
return Promise.resolve(users[id]);
}
}
用户视图.component.spec.ts:
user-view.component.spec.ts:
import {
beforeEachProviders,
describe,
expect,
it,
injectAsync,
TestComponentBuilder
} from 'angular2/testing';
import {provide} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {UserViewComponent} from './user-view.component';
import {UserService} from './user.service';
export function main() {
describe('User view component', () => {
beforeEachProviders(() => [
provide(RouteParams, { useValue: new RouteParams({ id: '0' }) }),
UserService
]);
it('should have a name', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb.createAsync(UserViewComponent)
.then((rootTC) => {
spyOn(console, 'info');
let uvDOMEl = rootTC.nativeElement;
rootTC.detectChanges();
expect(console.info).toHaveBeenCalledWith(0);
expect(DOM.querySelectorAll(uvDOMEl, 'h2').length).toBe(0);
});
}));
});
}
路由参数正确传递,但在运行测试之前视图没有改变.如何设置在解决 ngOnInit 中的承诺后发生的测试?
The route param is getting passed correctly, but the view hasn't changed before the tests are run. How do I set up a test that happens after the promise in ngOnInit is resolved?
推荐答案
Return a Promise
from #ngOnInit
:
Return a Promise
from #ngOnInit
:
ngOnInit(): Promise<any> {
const id: number = parseInt(this._routeParams.get('id'));
return this._userService
.getUser(id)
.then(user => {
console.info(user);
this.user = user;
});
}
几天前我遇到了同样的问题,发现这是最可行的解决方案.据我所知,它不会影响应用程序中的其他任何地方.由于 #ngOnInit
在源的 TypeScript 中没有指定返回类型,我怀疑源代码中的任何内容都期望从中返回值.
I ran into the same issue a few days back, and found this to be the most workable solution. As far as I can tell, it doesn't impact anywhere else in the application; since #ngOnInit
has no specified return type in the source's TypeScript, I doubt anything in the source code is expecting a return value from that.
在您的测试中,您将返回一个新的 Promise
:
In your test, you'd return a new Promise
:
it('should have a name', injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
// Create a new Promise to allow greater control over when the test finishes
//
return new Promise((resolve, reject) => {
tcb.createAsync(UserViewComponent)
.then((rootTC) => {
// Call ngOnInit manually and put your test inside the callback
//
rootTC.debugElement.componentInstance.ngOnInit().then(() => {
spyOn(console, 'info');
let uvDOMEl = rootTC.nativeElement;
rootTC.detectChanges();
expect(console.info).toHaveBeenCalledWith(0);
expect(DOM.querySelectorAll(uvDOMEl, 'h2').length).toBe(0);
// Test is done
//
resolve();
});
});
}));
}
这篇关于在 Angular 2 ngOnInit 中测试承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!