2017-08-29 49 views
0

我正在嘗試爲angular2中的身份驗證服務上的登錄方法編寫單元測試。我面臨的問題是Observable.subscribe是異步的,不會在我的測試中運行,因此localStorage.setItem永遠不會運行。我試圖讓我的代碼返回一個承諾,並使用茉莉花完成,但這似乎也不工作。我應該如何去測試這個功能?如何測試Angular2 Observable中的功能?

從認證服務代碼

login(username: string, password: string) { 

    const url = environment.apiUrl; 

    this._http.post(`https://${url}/authenticate`, {username, password}) 
    .map(res => res.json()) 
    .subscribe(
     data => localStorage.setItem('id_token', data.id_token), 
     error => console.log(error) 
    ); 
} 

單元測試

it('should set id_token',() => { 
    mockBackend.connections.subscribe((connection: MockConnection) => { 
    connection.mockRespond(validResponse); 
    }); 
    spyOn(localStorage, 'setItem').and.returnValue(undefined); 
    authService.login('admin', 'secret'); 
    expect(localStorage.setItem).toHaveBeenCalledWith('i am a token!'); 
}); 

回答

1

角度提供了用於測試的fakeasync工具來解決這樣的問題。

你只需要包裝測試中fakeasync,再之後是異步調用打勾(),這將允許任何異步方法繼續

導入之前完成以下到您的測試的任何方法

import { fakeAsync , tick} from '@angular/core/testing'; 

並修改你的測試如下;

it('should set id_token', fakeasync(() => { 
    mockBackend.connections.subscribe((connection: MockConnection) => { 
    connection.mockRespond(validResponse); 
    }); 
    spyOn(localStorage, 'setItem').and.returnValue(undefined); 
    authService.login('admin', 'secret'); 
    tick(); 
    expect(localStorage.setItem).toHaveBeenCalledWith('i am a token!'); 
})); 

https://angular.io/api/core/testing/fakeAsync