0

I am trying to learn how to rxjs marble test using testScheduler. When trying to test a behavior subject getter and setter I get the error Expected spy setVersatilityRowOptions to have been called with:[ VersatilityHeaderRowOptions({ onlyShowCertifiedOperators: true, showOffTeamOperators: false })] but it was never called.

Here is what my code looks like

My Service Functions

setVersatilityRowOptions(versatilityRowOptions: VersatilityHeaderRowOptions): void {
  this._versatilityRowOptions.next(versatilityRowOptions);
}

getVersatilityRowOptions(): Observable<VersatilityHeaderRowOptions> {
  return this.$versatilityRowOptions;
}

My Component Function I'm testing

updateVersatility(): void {
  this.versatilityApiService.getVersatilityRowOptions()
    .subscribe(versatilityRowOptions => {
        this.versatilityApiService.setVersatilityRowOptions(versatilityRowOptions);
  });
}

My Test File (I have mocked the object, the service, and the services functions in my spec file as well. Additionally, the service has been correctly injected into my spec file).

const testScheduler = new TestScheduler((actual, expected) => {
  expect(actual).toEqual(expected);
});

describe('updateVersatility()', () => {
  it('should update behavior subject', () => {
    testScheduler.run(({cold}) => {
      const source1$ = cold('--(x|)', {x: mockVersatilityHeaderRowOptions});  
    spyOn(component['versatilityApiService'],'getVersatilityRowOptions')
      .and.returnValue(source1$);
    spyOn(component['versatilityApiService'], 'setVersatilityRowOptions');

    component.updateVersatility();

    getTestScheduler().flush();

    fixture.detectChanges();

    expect(component['versatilityApiService'].getVersatilityRowOptions)
      .toHaveBeenCalled();
    expect(component['versatilityApiService'].setVersatilityRowOptions)
      .toHaveBeenCalledWith(mockVersatilityHeaderRowOptions);

});

I tried to run the test Scheduler and thought that the observable would flush and I could expect the setter to be called but it was not.

Yas Ikeda
  • 973
  • 1
  • 9
  • 16

1 Answers1

0

I thought it is similar to my case where a component subscribes to a RxJS observable. I also use NgRx Store and the observable is coming from it, so my solution here possibly doesn't exactly apply to your case, but hoping it does.

My solution uses TestScheduler.schedule from jasmine-marbles and fakeAsync from @angular/core/testing.

  it('should varify after observables emit', fakeAsync(() => { // <--
    let fixture = TestBed.createComponent(SomeComponent);
    let component = fixture.componentInstance;
    fixture.detectChanges();

    // make the observables in the component emit values

    getTestScheduler().schedule(() => { // <--
      fixture.detectChanges();

      // verify things about the component
      expect(component['someService'].setSomething).toHaveBeenCalled();
    ), time('|')); // <--
  });

Hopefully, it could also help in your case.

Yas Ikeda
  • 973
  • 1
  • 9
  • 16