2016-08-26 4 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); 
    }); 
} 

가 지금은 기능을 테스트하려면 : 현재 내가 각도 2 RC4 스민 2.4.x에서 를 사용하고 나는 정기적으로이 같은 HTTP 서비스를 호출하는 각도이 서비스가있다. 테스트를 위해 난 그냥 수행하여 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

당신은 분명히 당신의 주장 프레임 워크 (재스민)의 깊은 평등 assertion 함수를 전달해야합니다. 'new TestScheduler ((a, b) => expect (a) .toEqual (b))' –

+0

좋아, 이전 버전을 사용 했으므로 가까워지고있다. 스케줄러를 예약하고 싶을 때 (scheduleAbsolute가 [schedule] (https://github.com/ReactiveX/rxjs/blob/master/src/scheduler/VirtualTimeScheduler.ts)로 바뀜), ()을 수행하여 작업을 수행합니다. 'scheduler.schedule (null, 2000, 함수는 호출되지 않습니다. – stevehin

관련 문제