0

我不明白为什么.getValue()返回 Observable 的默认值而不是发出的最后一个值。在测试 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 测试时失败。

谢谢!

4

3 回答 3

0

原因是回调函数的异步性质catch。所以我认为如果你将你的期望语句包装在 中 setTimeout,并以异步方式运行测试,它就会变成绿色。

于 2019-09-24T11:38:05.293 回答
0

第一个断言是异步的。在内部,它会解决Observable,所以你确实会得到2.

然而,虽然这是未决的,但会触发其他两个断言。而且它们是同步的。没有什么可以保证您当时.next通话已经完成。所以你仍然得到初始值。

这就是为什么我建议不要使用的.getValue方法,BehaviorSubject而是正确订阅它。这样,您将通过始终执行异步操作来避免这种混乱。

于 2019-09-24T11:46:19.447 回答
0

即使我这样做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);
  }));
于 2019-09-24T12:22:17.057 回答