我有一个调用服务方法的组件。当服务方法返回可观察量时,它工作得很好,但是当我把它改成承诺时,测试开始失败。
测试的变化是:
加工:
测试:
const getPackListSpy = ppackService.listPacks.and.returnValue( of(packListResult) );
it('should show pack list', fakeAsync(() => {
fixture.detectChanges();
tick(5000);
fixture.detectChanges();
const packsInView = fixture.nativeElement.querySelectorAll('.packName').length;
expect(packsInView).toBe(2);
}));
元件:
this.protocolPackService.listPacks()
.subscribe((packs) => {
this.packs = packs;
});
更改为承诺后不起作用:
测试:
const getPackListSpy = ppackService.listPacks.and.returnValue( Promise.resolve(packListResult) );
元件:
this.packs = await this.protocolPackService.listPacks();
问题是我在模板中的项目列表在更改为承诺后没有显示任何数据(基于 this.packs
(。在测试环境之外的这两种情况下,该组件都可以正常工作。
知道可能出了什么问题吗?
组件代码:
ngOnInit() {
this.getUploadedPacks();
}
async getUploadedPacks() {
const packs = await this.protocolPackService.listPacks();
this.packs = [{
name: 'pack'
}];
this.packs = this.packs.concat(packs);
}
服务:
listPacks(): Promise<any> {
return this.http.get('packs').toPromise();
}
您必须使用一些方法来测试异步代码,例如角度测试库中的fakeAsync/tick
:
it('should show items', fakeAsync(() => {
const { comp, el, fixture } = setup();
fixture.detectChanges();
tick(1000);
fixture.detectChanges();
expect(comp.packs.length).toBe(2);
}));
在stackblitz上查看这个现场演示。
附言问题是,当您使用 Rxjs of
运算符模拟您的服务方法时,它将充当同步代码,例如:
console.log(1);
of(2).subscribe(v => console.log(v));
console.log(3);
此代码将控制台.log:1、2、3。
但是当你使用 Promise 时,它会像一个异步代码,例如:
console.log(1);
Promise.resolve(2).then(v => console.log(v));
console.log(3);
此代码将控制台.log:1、3、2。
这就是为什么在使用 Promise 来模拟你的服务方法的情况下,你必须编写单元测试,记住你正在处理异步代码。