user1722632
user1722632

Reputation: 23

Angular2 Unit test for Observable.interval

I have a service that polls data from server every 500 milliseconds. For this i have used Observable.interval().

Below is my code. I want to write the unit test for this service

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);
    });
  }
)));

Getting the error on running ng test:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Upvotes: 2

Views: 4970

Answers (2)

Amit Chigadani
Amit Chigadani

Reputation: 29775

You can increase the default timeout interval for jasmine. Assuming your test requires 30 seconds, you could do the following :

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);

Upvotes: 0

Teddy Sterne
Teddy Sterne

Reputation: 14219

You can use the fakeAsync testing function and the tick function to simulate the interval. Here is an example method and associated test demonstrating this behavior.

Component Method

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

Test Method

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
}));

Upvotes: 6

Related Questions