【问题标题】:How to test that an Observable does not emit in Angular Component which contains asynchronous logic如何测试 Observable 不会在包含异步逻辑的 Angular 组件中发出
【发布时间】:2019-01-30 18:15:22
【问题描述】:

假设我有一个 Angular 组件,它将 Observable myObs$ 定义为其属性之一。

在一个测试中,给定某些条件,我想测试myObs$ 不会通知。在逻辑中存在一些延迟,因此测试必须是异步的。

我正在使用 茉莉花

到目前为止,我已经能够制定这个解决方案:

it('async test', done => {
    let dataEmitted;
    myObs$
    .pipe(
      tap(data => dataEmitted = data),
    )
    .subscribe();
    setTimeout(() => {
      if (dataEmitted) {
        done.fail('should not emit');
      } else {
        done();
      }
    }, 1000);
  });

但我对此并不满意。我必须依靠setTimeout 来执行检查并调用done 函数。

关于如何正确执行此类测试的任何建议?同步解决方案不起作用,因为逻辑中存在内在的异步性。

【问题讨论】:

    标签: angular jasmine rxjs angular-test


    【解决方案1】:

    如果是基于setTimeout/debounceTime等的异步逻辑,可以使用fakeAsync()函数进行测试,该函数将替代 所有这些 异步 操作都带有 同步 操作,因此可以测试您的逻辑,因为它是同步的。您也可以使用 tick() 跳过 VM 轮次(它也会同步发生!)。使用此解决方案,您将拥有漂亮、干净、快速且可靠的单元测试。

    代码示例

    it('asynch test', fakeAsync(() => {
        let dataEmitted;
        myObs$.subscribe(data => dataEmitted = data);
    
        tick(1000);
        
        expect(dataEmitted).toBeUndefined();
    }));
    

    我建议您也检查负面情况,例如 tick(2000) 并检查它是否发出值。希望对您有所帮助。

    【讨论】:

    • 酷一个!谢谢! skip 运营商很花哨!我想知道它是否可以与tickfakeAsync 一起使用
    • 你说得对,我的意思是tick 但写了skip...我会编辑答案
    猜你喜欢
    • 2017-10-27
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2017-09-07
    • 2017-12-11
    • 2019-07-14
    相关资源
    最近更新 更多