2017-04-12 61 views
3

我很難讓單元測試與延遲運算符一起使用Observable。該應用程序構建在Angular 2上,並且測試在karma/jasmine中運行。我已經嘗試了異步和fakeAsync幫助器方法,但他們都沒有工作。單元測試延遲運算符可觀察

下面是一個簡化的代碼塊(沒有Angular 2)來解釋我的問題。

let mouseDownStream = Rx.Observable.fromEvent(document.body, 'mousedown'); 
let haveBeenCalled = false; 
mouseDownStream.delay(200).subscribe(() => haveBeenCalled = true); 

describe('mouse down event',() => { 
    it('it should emit an event stream after 200ms', (done) => { 
    document.body.dispatchEvent(new MouseEvent('mousedown')) 
    expect(haveBeenCalled).toBeFalsy(); 

    // Don't want this setTimeout should use Angular's tick(200) method instead but it's not working. 
    setTimeout(() => { 
     expect(haveBeenCalled).toBeTruthy(); 
     done(); 
    }, 200) 
    }); 
}); 

JSBin

+0

你越來越像一些錯誤「不能打電話的setInterval裏面的異步區「?如果是這樣,從我記憶中,我不認爲這是可能的。你在做什麼是最好的方法 –

+0

我沒有得到任何上述例子的錯誤。測試通過。我只是不想使用所有測試的設置超時。 – bjorkblom

+0

不,我的意思是你與異步和fakeAsync得到錯誤 –

回答

0

訣竅是使用不同的調度器。有一個測試專用的調度程序叫... TestScheduler。這與大理石圖相結合可以測試異步流。

這裏是從官方spec of the delay operator一個例子:

it('should delay by absolute time period',() => { 
    const e1 = hot('--a--b--| '); 
    const t = time( '---|  '); 
    const expected = '-----a--b--|'; 
    const subs =  '^   !'; 

    const absoluteDelay = new Date(rxTestScheduler.now() + t); 
    const result = e1.delay(absoluteDelay, rxTestScheduler); 

    expectObservable(result).toBe(expected); 
    expectSubscriptions(e1.subscriptions).toBe(subs); 
}); 

有更多關於這個話題隱藏在「官方」文檔:https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md

+0

我如何在上面的示例中應用這個? – bjorkblom