【问题标题】:How to test if returned Observable is EMPTY如何测试返回的 Observable 是否为 EMPTY
【发布时间】:2021-02-23 11:28:46
【问题描述】:

在一种情况下,我有一个返回 EMPTY Observable 的效果。我正在尝试测试这种情况,但我似乎无法弄清楚如何测试EMPTY Observable? 我的代码如下:

效果:

   effect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(someAction),
      mergeMap(([action]) => {
        if (someCondition) {
          return EMPTY <-- this is what I am trying to test
        }
        return someServiceCall.pipe(
          map((offers) => //dispatch some action,
          catchError((error: string) => // dispatch another action),
        )
      }),
    ),
  )

这是我的单元测试尝试,但失败了

Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL).

考虑到条件在测试中已经满足:

  it('should return EMPTY when ...', (done) => {
    actions$ = of(someAction)
    effects.effect$.subscribe((res) => {
      expect(res).toEqual(never)
      done()
    })
  })

如果返回是of(null) 而不是EMPTY,我可以让它工作。但我真的很想知道如何测试这个案例。

【问题讨论】:

  • EMPTY undefinedexpect(res).toBe(undefined) 有效吗?
  • @AshishRanjan EMPTYof(never)。在尝试您的建议时,它也会因Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL) 而失败
  • 我正在阅读关于 EMPTY,NEVER 的内容,因此它们根本不会发出任何东西。 EMPTY 终止并且 NEVER 甚至不终止。这意味着,如果您使用的是 EMPTY,也许您可​​以检查完整的回调

标签: angular rxjs jasmine karma-jasmine ngrx-effects


【解决方案1】:

似乎我们在 RxJs 中有一个特定的操作来检查 observable 是否为空。操作是isEmpty()

it('should return EMPTY when ...', (done) => {
    actions$ = of(someAction)
    effects.effect$.pipe(isEmpty()).subscribe( (res) => {
                                               expect(res).toEqual(true)
                                               done()
                                              });

只有当 observable 以空返回时,res 才会为真

【讨论】:

    【解决方案2】:

    EMPTY 不发出任何东西,而是终止。因此,不会调用成功回调,但会触发完整的回调。

    如果适合您的测试,也许您可​​以检查完整的回调。

    请原谅我对测试的了解较少,但在这里我无法放置适当的断言语句。所以,我遵循了这种方法,请根据需要进行调整,更改,唯一目的是检查是否调用了complete cb。

     it('should return EMPTY when ...', (done) => {
        actions$ = of(someAction)
        const success = () => {};
        const error = () => {};
        const complete = () => {};
    
        effects.getShopOffersInTimeRange$.subscribe(success, error, complete);
    
        setTimeout(() => {
          expect(complete).toHaveBeenCalled();
          done();
        });
      });
    

    还没有测试过代码,希望它可以工作。

    【讨论】:

    • 发出相同的Error: Timeout。我认为既然EMPTY 没有发出任何东西,那么subscribe 永远不会被触发。
    • @Lossan:在这种情况下不应该发生超时,因为 setTimeout 最终会调用done()。并且 EMPTY 不会发出,是的。但终止。 stackblitz.com/edit/rxjs-bhppxx?devtoolsheight=60
    猜你喜欢
    • 2010-12-14
    • 2018-06-16
    • 2021-09-03
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    相关资源
    最近更新 更多