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

Popular posts from this blog

jOOQ update returning clause with Oracle -

java - Warning equals/hashCode on @Data annotation lombok with inheritance -

java - BasicPathUsageException: Cannot join to attribute of basic type -