gpt4 book ai didi

unit-testing - 运行使用 "Cannot use setInterval from within an async zone test"调用 setTimeout 错误的 Angular2 测试

转载 作者:太空狗 更新时间:2023-10-29 17:35:00 25 4
gpt4 key购买 nike

我正在升级我们的 Angular2 应用程序以使用 rc4,但我的单元测试开始出现错误:

Cannot use setInterval from within an async zone test

我的小部件从其 ngOnInit 方法请求数据,并在发出该请求时放置一个加载指示器。我的模拟服务在 1 毫秒后返回一些数据。

这是暴露问题的简化版本

import { inject, async, TestComponentBuilder, ComponentFixture} from '@angular/core/testing';
import {Http, Headers, RequestOptions, Response, HTTP_PROVIDERS} from '@angular/http';
import {provide, Component} from '@angular/core';

import {Observable} from "rxjs/Rx";

class MyService {
constructor(private _http: Http) {}
getData() {
return this._http.get('/some/rule').map(resp => resp.text());
}
}

@Component({
template: `<div>
<div class="loader" *ngIf="_isLoading">Loading</div>
<div class="data" *ngIf="_data">{{_data}}</div>
</div>`
})
class FakeComponent {
private _isLoading: boolean = false;
private _data: string = '';

constructor(private _service: MyService) {}

ngOnInit() {
this._isLoading = true;
this._service.getData().subscribe(data => {
this._isLoading = false;
this._data = data;
});
}
}

describe('FakeComponent', () => {
var service = new MyService(null);
var _fixture:ComponentFixture<FakeComponent>;

beforeEach(async(inject([TestComponentBuilder], (tcb:TestComponentBuilder) => {
return tcb
.overrideProviders(FakeComponent, [
HTTP_PROVIDERS,
provide(MyService, {useValue: service}),
])
.createAsync(FakeComponent)
.then((fixture:ComponentFixture<FakeComponent>) => {
_fixture = fixture;
});
})));

it('Shows loading while fetching data', (cb) => {
// Make the call to getData take one ms so we can verify its state while the request is pending
// Error occurs here, when the widget is initialized and sends out an XHR
spyOn(service, 'getData').and.returnValue(Observable.of('value').delay(1));
_fixture.detectChanges();
expect(_fixture.nativeElement.querySelector('.loader')).toBeTruthy();
// Wait a few ms, should not be loading
// This doesn't seem to be the problem
setTimeout(() => {
_fixture.detectChanges();
expect(_fixture.nativeElement.querySelector('.loader')).toBeFalsy();
cb();
}, 10);
});
});

这在 Angular2 rc1 中运行良好,但在 rc4 中抛出错误,有什么建议吗?

此外,如果您直接从测试本身使用 setTimeout,则不会出现错误

        fit('lets you run timeouts', async(() => {
setTimeout(() => {
expect(1).toBe(1);
}, 10);
}));

最佳答案

我发现出于某种原因,您不能在测试中使用通过 Observable.of(anything).delay() 创建的 promise 。

我的解决方案是自己实现该行,考虑到问题中发布的另一个示例确实有效,这几乎是有道理的。

// This is what we should be doing, but somehow, it isn't working.
// return Observable.of(result).delay(0));
function createDelayedObservable <T>(result:any, time:number = 0):Observable<T> {
return new Observable<T>(observer => {
setTimeout(() => observer.next(result), time);
});
}

但是,我仍然不明白为什么以下不会失败,所以我不接受我自己的回答,希望对区域有深入了解的人可以告诉我发生了什么。

it('should be able to use delay in tests', (cb) => {
var obs = Observable.of(1).delay(0);
obs.subscribe(val => {
expect(val).toBe(1);
cb()
});
});

关于unit-testing - 运行使用 "Cannot use setInterval from within an async zone test"调用 setTimeout 错误的 Angular2 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38574837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com