如何在Angular2 Observable中测试功能?

时间:2017-08-29 03:15:14

标签: angular unit-testing jasmine observable

我正在尝试在angular2中的身份验证服务上为登录方法编写单元测试。我面临的问题是Observable.subscribe是异步的,并且不在我的测试中运行,因此永远不会运行localStorage.setItem。我试图让我的代码返回一个承诺并使用茉莉花完成,但这似乎也没有用。我该如何测试这个功能?

来自身份验证服务的代码

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 个答案:

答案 0 :(得分:1)

Angular提供了一个伪同步实用程序,用于测试以解决此类问题。

你只需要在fakeasync中包装你的测试,然后在异步调用tick()的任何方法之后允许任何异步方法在继续之前完成

将以下内容导入您的测试

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