typescriptrxjsjestjsrxjs-marbles

RxJS BehaviorSubject getValue inconsistency after value emitted (while testing in Jest)


I don't understand why .getValue() returns the default value of the Observable and not the last value emitted. When testing the Observable, it correctly returns the emitted value.

class TestA {
  readonly aSource: BehaviorSubject<number> = new BehaviorSubject(null);

  getA(): number {
    return this.aSource.getValue();
  }

  promise(): void {
    Promise.reject()
      .catch(() => {
        this.aSource.next(2);

        console.log(this.getA()); // Outputs: 2
      });
  }
}

describe('TestA', () => {
  it('promise', () => {
    const a = new TestA();
    a.promise();

    // Test 1 OK
    expect(a.aSource.asObservable()).toBeObservable(hot('a', {a: 2}));

    // Test 2 FAIL (returns null)
    expect(a.aSource.getValue()).toEqual(2);

    // Test 3 FAIL (returns null)
    expect(a.getA()).toEqual(2);
  });
});

To clarify, the getValue() method works fine outsude tests, it only fails while testing with Jest.

Thanks!


Solution

  • Even if I do Promise.reject() the code doesn't turnout to be synchronous, so in this case you need to flush execution queue in order to test that code.

    A solution using Angular helper functions would be:

      it('promise', fakeAsync(() => {
        const a = new TestA();
        a.promise();
    
        flush();
    
        expect(a.aSource.asObservable()).toBeObservable(hot('a', {a: 2}));
        expect(a.aSource.getValue()).toEqual(2);
        expect(a.getA()).toEqual(2);
      }));