fakeAsync 是否定义范围?使用 Jasmine 和 fakeAsync 测试 RXJS 超时

时间:2021-05-31 15:41:39

标签: angular testing rxjs jasmine timeout

今天我很难弄清楚几个与以下规范类似的问题:

import {fakeAsync, tick} from '@angular/core/testing';
import {NEVER} from 'rxjs';
import {timeout} from 'rxjs/operators';

describe('Test Spec', () => {

  let invokedErrorBlock = false;

  beforeEach(() => invokedErrorBlock = false);

  describe('using fakeAsync', () => {

    // works as expected
    it('should throw a timeout exception, definition in spec', fakeAsync(() => {

      NEVER.pipe(timeout(1000)).subscribe(
        success => fail(),
        error => invokedErrorBlock = true
      );

      expect(invokedErrorBlock).toBeFalse();
      tick(1000);
      expect(invokedErrorBlock).toBeTrue();

    }));

    // works as expected
    it('should throw a timeout exception, definition in function', fakeAsync(() => {

      setupObservable();

      expect(invokedErrorBlock).toBeFalse();
      tick(1000);
      expect(invokedErrorBlock).toBeTrue();

    }));
  });

[...]

这两个按预期工作。想象一下 NEVER-observable 是更复杂的东西,必须在每个规范之前设置。因此我认为将它移到 beforeEach 方法中是个好主意

[...]

  // doesn't work - tick doesn't influence timeout
  describe('using fakeAsync in spec, not beforeEach', () => {

    beforeEach(() => setupObservable());

    it('should throw a timeout exception, definition in beforeEach', fakeAsync(() => {

      expect(invokedErrorBlock).toBeFalse();
      tick(1000);
      expect(invokedErrorBlock).toBeTrue();

    }));
  });

[...]

此规范失败,因为滴答未触发超时。

[...]
  // doesn't work - tick doesn't influence timeout + 1 periodic timer in queue
  describe('using fakeAsync in spec and beforeEach', () => {

    beforeEach(fakeAsync(() => setupObservable()));

    it('should throw a timeout exception, definition in beforeEach', fakeAsync(() => {

      expect(invokedErrorBlock).toBeFalse();
      tick(1000);
      expect(invokedErrorBlock).toBeTrue();

    }));
  });

  function setupObservable() {
    NEVER.pipe(timeout(1000)).subscribe(
      success => fail(),
      error => invokedErrorBlock = true
    );
  }
});

虽然此规范也因未满足预期(超时未由滴答触发)和队列中有 1 个定期计时器而失败。

谁能解释为什么它不起作用?对我来说,fakeAsync 似乎定义了某种范围时移,通过刻度正在工作。由于刻度和 Observable 没有在同一个“范围”内定义,所以它不起作用 - 这是对的吗?

我应该如何构建代码,这样我就不必在每个规范的开头重复设置?

0 个答案:

没有答案