RxJS BehaviorSubject getValue несоответствие после испущенного значения (при тестировании в Jest) - PullRequest
0 голосов
/ 24 сентября 2019

Я не понимаю, почему .getValue() возвращает значение по умолчанию для наблюдаемого, а не последнее выбранное значение.При тестировании Observable он корректно возвращает испущенное значение.

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);
  });
});

Чтобы уточнить, метод getValue() отлично работает, не проверяя тесты, он только дает сбой при тестировании с Jest.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 24 сентября 2019

Первое утверждение является асинхронным.Внутренне это разрешит Observable, так что вы действительно получите 2.

Однако, пока это ожидается, два других утверждения срабатывают.И они синхронны.Ничто не гарантирует вам, что в то время звонок .next был сделан.Таким образом, вы по-прежнему получаете начальное значение.

Вот почему я бы рекомендовал не использовать .getValue метод BehaviorSubject и скорее подписаться на него должным образом.Таким образом, вы избежите такой путаницы, всегда делая асинхронные операции.

0 голосов
/ 24 сентября 2019

Даже если я сделаю Promise.reject(), код не будет синхронным, поэтому в этом случае вам необходимо очистить очередь выполнения для проверки этого кода.

Решение, использующее вспомогательные функции Angular, будетбыть:

  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);
  }));
0 голосов
/ 24 сентября 2019

Причина - асинхронный характер функции обратного вызова catch.Поэтому я думаю, что если вы обернетесь в ожидаемое выражение в setTimeout и запустите проверку как асинхронную, она станет зеленой.

...