Angular - unit test for a subscribe function in a component

You need this for version rxjs@6 and above. For older rxjs version answer is below:

    import { of } from 'rxjs';

    it("should call getUsers and return list of users", async(() => {
      const response: User[] = [];

      spyOn(userService, 'getUsers').and.returnValue(of(response))

      homeComponent.getUsers();

      fixture.detectChanges();
    
      expect(homeComponent.listOfUsers).toEqual(response);
    }));

For old rxjs version change import from:

    import { of } from 'rxjs';

to

    import { of } from 'rxjs/observable/of';

in your case you can use fakeAsync also used tick() to detect change. you can add time to tick also to indicate how log to wait. eg tick(1000)

Code is modified from Sharikov Vladislav

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

it("should call getUsers and return list of users", fakeAsync(() => {
  const response: User[] = [];
  spyOn(userService, 'getUsers').and.returnValue(of(response))
  homeComponent.getUsers();
  tick();
  expect(homeComponent.listOfUsers).toEqual(response);
}));

I had similar issue and to make it work I used the arbitrary function (in the following code it's named done) inside of it


  it("should call getUsers and return list of users", async((done) => {
    // Arrange
    let response: User[] = [];

    // Act
    homeComponent.getUsers();

    fixture.detectChanges();
    fixture.whenStable().subscribe(() => {
        expect(homeComponent.listOfUsers).toEqual(response);
        done();
    });
  }));