【问题标题】:Angular2 Unit test for Observable.intervalObservable.interval 的 Angular2 单元测试
【发布时间】:2017-11-29 13:18:48
【问题描述】:

我有一项服务每 500 毫秒从服务器轮询一次数据。为此我使用了Observable.interval()

下面是我的代码。我想为此服务编写单元测试

service.ts:

pollData() {
       Observable.interval(500).mergeMap(() =>
       this._http
      .get(url, { headers: headers })
      .map((resp: Response) => resp.json())
});

Service.spec.ts:

it('should get the response correctly', async(inject(
  [SomeService, MockBackend], (service, mockBackend) => {
    mockBackend.connections.subscribe((connection: MockConnection) => {
      connection.mockRespond(new Response(new ResponseOptions({ body: 
      mockResponse})));
   });
    const result = service.pollData();

    result.subscribe(response => {
       expect(response).toEqual(mockResponse);
    });
  }
)));

在运行 ng test 时遇到错误:

错误:超时 - 未在超时内调用异步回调 由 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定。

【问题讨论】:

    标签: angular unit-testing karma-runner


    【解决方案1】:

    您可以使用fakeAsync 测试函数和tick 函数来模拟区间。以下是演示此行为的示例方法和相关测试。

    组件方法

    public testMe() {
      return Observable.interval(500).mergeMap((period: number) => {
        return Observable.of(period);
      });
    }
    

    测试方法

    it('should test method with interval', fakeAsync(() => {
      const obs = component.testMe();
      let currentVal = undefined;
      const sub = obs.subscribe((v) => {
        currentVal = v;
      });
      tick(500);
      expect(currentVal).toEqual(0);
      tick(500);
      expect(currentVal).toEqual(1);
      tick(500);
      expect(currentVal).toEqual(2);
      /* ... */
      sub.unsubscribe(); // must unsubscribe or Observable will keep emitting resulting in an error
    }));
    

    【讨论】:

    • 我认为如果方法不返回 Observable 就不能使用这种方法?例如,我的 ngOnInit 中运行了一个间隔,因此我无法访问测试中的 Observable。
    • 如果您无法访问 observable,那么将很难测试。也许它是从您可以存根的服务中创建的,或者还有另一个值是可以测试的内部 observable 的结果?
    【解决方案2】:

    您可以增加jasmine 的默认超时间隔。假设您的测试需要 30 秒,您可以执行以下操作:

    it('should get the response correctly', async(inject(
      [SomeService, MockBackend], (service, mockBackend) => {
        mockBackend.connections.subscribe((connection: MockConnection) => {
          connection.mockRespond(new Response(new ResponseOptions({ body: 
          mockResponse})));
       });
        const result = service.pollData();
    
        result.subscribe(response => {
           expect(response).toEqual(mockResponse);
        });
      }
       // increasing the jasmine.DEFAULT_TIMEOUT_INTERVAL to 30s.
    )), 30000);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 2016-10-19
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      相关资源
      最近更新 更多