1
votes

I have a component with the following ngOnInit() method:

ngOnInit() {
  combineLatest([
    this.observable1,
    this.observable2
  ])
  .pipe(takeUntil(this.unsubscribe$))
  .subscribe(([data1, data2]) => {
    this.processData(data1, data2);
  });
}

I want to write a test to verify that the processData() method is called.

I tried something like this:

it('should call processData', ()=> {
   ... make sure each observable1 and observable2 will emit a value
   spyOn(component, 'processData');
   fixture.detectChanges();
   expect(component.processData).toHaveBeenCalled();
}));

expect(component.processData).toHaveBeenCalled() will always return false, it doesn't seem to wait until both observables emit a value.

My question is how to test such code? How to test that a method was called inside a subscribe function of an async rxjs operator?

1
You'll most likely have to stub the observables as well. It may not work now because they're emitting values asynchronously. Did you consider using something like spyOn(comp, 'observable1').and.returnValue(of('dummy data')) ? - Andrei Gătej

1 Answers

0
votes

The first question is what do this.observable1 and this.observable2 do?

To trigger this.processData both of them should emit at least once. Might you great if you could share more code of the test and how observable1 and observable2 are created.

I would suggest to change the test to the next style

it('should call processData', ()=> {
   // firstly set the spy
   spyOn(component, 'processData');

   // secondly we need to fake our observables
   component.observable1 = of(1);
   component.observable2 = of(2);

   // now we trigger the flow
   component.ngOnInit();

   // clean up
   component.unsubscribe$.next();
   component.unsubscribe$.complete();

   // assertions
   expect(component.processData).toHaveBeenCalledWith(1, 2);
}));