3

I'm using Angular 5 with Jasmine and Karma. I'm trying to test whether a certain function works but my subscribe doesn't trigger during unit testing. this causes my unit test to fail as I'm using the done function of jasmine. I want to make this unit test succeed.

I've set the timeout interval to 20 seconds to see if it just took a while (which it shouldn't).

I've tried to use async and fakeasync as well, but it doesn't trigger. Is it possible for me to make the subscription to trigger?

this is the code ive got:

describe('FilterService', () => {
  let service: FilterService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [FilterService]
    });
    service = TestBed.get(FilterService);
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
  });

  it("SetItemsToFilterByAndApplyFilters should set ItemsToFilterBy and set the InFilter property", (done: DoneFn) => {
    //arrange
    let item1: any = new Organisation();
    item1.Id = 1;
    item1.InFilter = true;
    let item2: any = new Organisation();
    item1.Id = 2;
    item1.InFilter = false;

    let itemNew1: any = new Organisation();
    itemNew1.Id = 1;
    let itemNew2: any = new Organisation();
    itemNew2.Id = 2;

    service.SetItemsToFilterBy([item1, item2]);
    let spy = spyOn(service.ItemsToFilterBy$, 'subscribe');

    //act
    service.SetItemsToFilterByAndApplyFilters([itemNew1, itemNew2]);
    //assert
    service.ItemsToFilterBy$.subscribe(result => {
      let result1 = _.find(result, item => {
        return item.Id == itemNew1.Id;
      });

      let result2 = _.find(result, item => {
        return item.Id == itemNew2.Id;
      });

      expect(result1.InFilter).toBeTruthy();
      expect(result2.InFilter).toBeFalsy();
      done();
    });
  });
});

this is the code that worked with thanks to Basavaraj Bhusani

      it("SetItemsToFilterByAndApplyFilters should set ItemsToFilterBy and set the InFilter property", (done: DoneFn) => {

    //arrange
    let spy = spyOn(service.ItemsToFilterBy$, 'subscribe').and.callThrough();

    let item1: any = new Organisation();
    item1.Id = 1;
    item1.InFilter = true;
    let item2: any = new Organisation();
    item2.Id = 2;
    item2.InFilter = false;

    let itemNew1: any = new Organisation();
    itemNew1.Id = 1;
    let itemNew2: any = new Organisation();
    itemNew2.Id = 2;

    service.SetItemsToFilterBy([item1, item2]);

    //act
    service.SetItemsToFilterByAndApplyFilters([itemNew1, itemNew2]);

    //assert
    service.ItemsToFilterBy$.subscribe(result => {
      let result1 = _.find(result, item => {
        return item.Id == itemNew1.Id;
      });

      let result2 = _.find(result, item => {
        return item.Id == itemNew2.Id;
      });

      expect(result1.InFilter).toBeTruthy();
      expect(result2.InFilter).toBeFalsy();
      done();
    });
    expect(spy).toHaveBeenCalled();
  });
});
pgSystemTester
  • 8,979
  • 2
  • 23
  • 49
D. Berg
  • 143
  • 1
  • 2
  • 7

1 Answers1

5

If service.ItemsToFilterBy$ is Subject<any>(), not BehaviorSubject or ReplaySubject, subscribe to service.ItemsToFilterBy$ in the beginning of your spec. Read here.

Use the callThrough() method by jasmine when you spy on a method. spyOn(service.ItemsToFilterBy$, 'subscribe')

i.e.

const spy = spyOn(service.ItemsToFilterBy$, 'subscribe').and.callThrough();

Read about callThrough here https://jasmine.github.io/2.0/introduction.html

Philipp Meissner
  • 5,273
  • 5
  • 34
  • 59
Basavaraj Bhusani
  • 5,375
  • 2
  • 16
  • 24