2016-08-26 17 views
4

こんにちは、Angular2、Karma、Jasmineは比較的新しいです。今、私は機能をテストしたいユニットテストRxJS Observable.timer(typescript、karma、jasmineを使用)

getDataFromDb() { return Observable.timer(0, 2000).flatMap(() => { 
     return this.http.get(this.backendUrl) 
      .map(this.extractData) 
      .catch(this.handleError); 
    }); 
} 

:現在、私は、私は定期的にこのようなHTTPサービスを呼び出す角度2サービスを持って角度2 RC4ジャスミン2.4.xの を使用しています。テストの目的のために私はちょうど行うことでObservable.timerずに別の機能に「http.get」をテストしています

const mockHttpProvider = { 
    deps: [MockBackend, BaseRequestOptions], 
    useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => { 
     return new Http(backend, defaultOptions); 
    } 
} 

describe('data.service test suite',() => { 
    var dataFromDbExpected: any; 

    beforeEachProviders(() => { 
     return [ 
      DataService, 
      MockBackend, 
      BaseRequestOptions, 
      provide(Http, mockHttpProvider), 
     ]; 
    }); 

    it('http call to obtain data', 
     inject(
      [DataService, MockBackend], 
      fakeAsync((service: DataService, backend: MockBackend) => { 
       backend.connections.subscribe((connection: MockConnection) => { 
        dataFromDbExpected = 'myData'; 
        let mockResponseBody: any = 'myData'; 
        let response = new ResponseOptions({ body: mockResponseBody }); 
        connection.mockRespond(new Response(response)); 

       }); 
       const parsedData$ = service.getDataFromDb() 
        .subscribe(response => { 
         console.log(response); 
         expect(response).toEqual(dataFromDbExpected); 
        }); 
      }))); 
}); 

が、私は明らかにObservable.timerと全体の機能をテストしたいです。私はrxjsフレームワークのTestSchedulerを使いたいと思うかもしれませんが、x回だけタイマ関数を繰り返すように指示する方法はありますか?私はタイプコピーの文脈でそれを使用しているドキュメントを見つけることはできません。

編集:私が使用しているrxjs 5ベータ6

編集:あなたは内部のタイマーメソッドにTestSchedulerを注入する必要がある

describe('when getData',() => { 
    let backend: MockBackend; 
    let service: MyService; 
    let fakeData: MyData[]; 
    let response: Response; 
    let scheduler: TestScheduler; 

    beforeEach(inject([Http, XHRBackend], (http: Http, be: MockBackend) => { 
     backend = be; 
     service = new MyService(http); 
     fakeData = [{myfake: 'data'}]; 
     let options = new ResponseOptions({ status: 200, body: fakeData }); 
     response = new Response(options); 

     scheduler = new TestScheduler((a, b) => expect(a).toEqual(b)); 
     const originalTimer = Observable.timer; 
     spyOn(Observable, 'timer').and.callFake(function (initialDelay, dueTime) { 
      return originalTimer.call(this, initialDelay, dueTime, scheduler); 
     }); 
    })); 
    it('Should do myTest', async(inject([],() => { 
     backend.connections.subscribe((c: MockConnection) => c.mockRespond(response)); 
     scheduler.schedule(() => { 
      service.getMyData().subscribe(
       myData => { 
        expect(myData.length).toBe(3, 
         'should have expected ...'); 
       }); 
     }, 2000, null); 
     scheduler.flush(); 
    }))); 
}); 

答えて

6

:2.0.0角度の最終リリースのための例を働い追加しましたbeforeEachパーツ:その後

beforeEach(function() { 
    this.scheduler = new TestScheduler(); 
    const originalTimer = Observable.timer; 
    spyOn(Observable, 'timer').and.callFake(function(initialDelay, dueTime) { 
    return originalTimer.call(this, initialDelay, dueTime, this.scheduler); 
    }); 
}); 

あなたはscheduleAbsoluteとの時間を完全に制御を持っている:

this.scheduler.schedule(() => { 
    // should have been called once 
    // You can put your test code here 
}, 1999, null); 

this.scheduler.schedule(() => { 
    // should have been called twice 
    // You can put your test code here 
}, 2000, null); 

this.scheduler.schedule(() => { 
    // should have been called three times 
    // You can put your test code here 
}, 4000, null); 

this.scheduler.flush(); 

TestSchedulerを起動するにはscheduler.flush()が必要です。

編集:それをX回しかテストしない場合は、scheduleAbsolute関数を必要に応じて(そして、絶対絶対時間をミリ秒で)頻繁に使用してください。

EDIT2:私は行方不明スケジューラは

EDIT3を開始追加:私は、インターフェースが変更されているようですので、RxJs5

+1

で作業する必要があり、それを変更しました。 TestSchedulerはコンストラクタ内にassertDeepEqualを想定しています。[link](https://github.com/ReactiveX/rxjs/blob/master/src/testing/TestScheduler.ts)を参照してください。私は少し混乱していますが、私はTestSchedulerの作成で何を主張すべきですか? – stevehin

+0

アサーション・フレームワーク(ジャスミン)のディープ・イコライゼーション・アサーション関数を渡す必要があるようです。 'new TestScheduler((a、b)=> expect(a).toEqual(b))' –

+0

これは以前のものだったので、近づいてきました。スケジューラのスケジュールを設定したいときは、scheduleAbsoluteが[schedule](https://github.com/ReactiveX/rxjs/blob/master/src/scheduler/VirtualTimeScheduler.ts)に置き換えられました。 ()スケジューラのスケジューリング(null、2000、()=> {dataService.getDataFromDb()。サブスクリプション(レスポンス=> {期待(応答).toEqual(getVehiclesFromDBRespose);});}); ' 関数は決して呼び出されません。 – stevehin

関連する問題