我有一个相当典型的简单ng2组件,它调用服务来获取一些数据(轮播项目) . 它还使用setInterval每隔n秒在UI中自动切换轮播幻灯片 . 它运行得很好,但是当运行Jasmine测试时,我得到错误:“不能在异步测试区域内使用setInterval” .
我尝试在this.zone.runOutsideAngular(()=> 中包装setInterval调用,但错误仍然存在 . 我认为改变测试以在fakeAsync区域中运行会解决问题,但后来我得到一个错误,说不允许在fakeAsync测试区内进行XHR调用(这确实有意义) .
如何同时使用服务发出的XHR调用和间隔,同时仍能测试组件?我正在使用ng2 rc4,由angular-cli生成的项目 . 提前谢谢了 .
我的组件代码:
constructor(private carouselService: CarouselService) {
}
ngOnInit() {
this.carouselService.getItems().subscribe(items => {
this.items = items;
});
this.interval = setInterval(() => {
this.forward();
}, this.intervalMs);
}
而且来自Jasmine规范:
it('should display carousel items', async(() => {
testComponentBuilder
.overrideProviders(CarouselComponent, [provide(CarouselService, { useClass: CarouselServiceMock })])
.createAsync(CarouselComponent).then((fixture: ComponentFixture<CarouselComponent>) => {
fixture.detectChanges();
let compiled = fixture.debugElement.nativeElement;
// some expectations here;
});
}));
3 回答
清洁代码是可测试的代码 .
setInterval
有时难以测试,因为时机永远不会完美 . 您应该将setTimeout
抽象为可以模拟测试的服务 . 在模拟中,您可以使用控件来处理间隔的每个刻度 . 例如使用
MockIntervalService
,您现在可以控制每个滴答,这在测试期间更容易推理 . 还有一个 Spy 来检查组件被销毁时是否调用clearInterval
方法 .对于
CarouselService
,因为它也是异步的,请参阅this post以获得一个好的解决方案 .以下是使用前面提到的服务的完整示例(使用RC 6) .
我遇到了同样的问题:具体来说,当第三方服务从测试中调用_1310442时,得到这个错误:
你可以模拟调用,但这并不总是可取的,因为你可能真的想测试与另一个模块的交互 .
我在我的情况下通过使用Jasmine(> = 2.0)async support而不是Angulars的
async()
来解决它:使用Observable怎么样? https://github.com/angular/angular/issues/6539要测试它们,您应该使用.toPromise()方法