unit testing - Running Angular2 tests that call setTimeout errors with "Cannot use setInterval from within an async zone test" -
i'm upgrading our angular2 app use rc4 , started getting error on unit tests:
cannot use setinterval within async zone test
my widget makes request data ngoninit
method , puts loading indicator while request made. mocked service returns data after 1ms.
here's simplified version exposes problem
import { inject, async, testcomponentbuilder, componentfixture} '@angular/core/testing'; import {http, headers, requestoptions, response, http_providers} '@angular/http'; import {provide, component} '@angular/core'; import {observable} "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 call getdata take 1 ms can verify state while request pending // error occurs here, when widget initialized , sends out xhr spyon(service, 'getdata').and.returnvalue(observable.of('value').delay(1)); _fixture.detectchanges(); expect(_fixture.nativeelement.queryselector('.loader')).tobetruthy(); // wait few ms, should not loading // doesn't seem problem settimeout(() => { _fixture.detectchanges(); expect(_fixture.nativeelement.queryselector('.loader')).tobefalsy(); cb(); }, 10); }); });
this working fine in angular2 rc1 , throws error in rc4, suggestions?
also, there no errors if use settimeout
directly test itself
fit('lets run timeouts', async(() => { settimeout(() => { expect(1).tobe(1); }, 10); }));
i've found reason, cannot use promise created observable.of(anything).delay()
in test.
my solution implement line myself, makes sense considering other example posted in question did work.
// should doing, somehow, 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); }); }
however, still don't understand why following doesn't fail, i'm not accepting own answer in hopes solid understanding of zones can tell me what's happening.
it('should able use delay in tests', (cb) => { var obs = observable.of(1).delay(0); obs.subscribe(val => { expect(val).tobe(1); cb() }); });
Comments
Post a Comment