如何模拟 RxJs 6 计时器?

2023-11-26

我们最近从 Angular 5 更新到 Angular 6,并随之更新为 RxJs 6。 作为迁移的一部分,计时器的使用已更改为:

Observable.timer()

to

timer()

在我们的测试中有很多地方我们使用以下模式模拟计时器可观察值。

let timerObserver: Observer<any>;

 beforeEach(() => {
 spyOn(Observable, 'timer').and.returnValue(Observable.create(
    ((observer: Observer<any>) => {
      timerObserver  = observer;
    })
  ));
});

it(`should not have any notifications by default`, () => {
   timerObserver.next('');
   ...
});

有人知道如何迁移这种模式吗?


Edit:我在这里创建了问题的简化说明:

https://stackblitz.com/edit/angular-v6-testing-template-nm7add

// Hello.Component
      ngOnInit() {
        const timer$ = timer(30);
        timer$.subscribe(() => {
          this.testMe = 'this has been changed';
        });
      }

// Hello.component.spec
  it('should set testMe after a given timer', fakeAsync(() => {
    tick(50);
    expect(fixture.componentInstance.testMe).toBe('this has been changed');
  }));

在此示例中,我尝试让计时器触发,而不等待计时器解析。


当你正在使用fakeAsync,你可以依赖它的补丁setInterval伪造实施timer可观察到的。

但是,您需要破坏asyncScheduler实例的now方法,当它返回时Date.now()。 (严格来说,这对于timerobservable,正如您使用过的那样,但对于其他一些 observable 来说这很重要 - 例如返回的可观察量delay操作员)。

如果你使用的话,你可以很容易地让事情开始工作beforeEach and afterEach破坏now方法并配置一个跟踪假时间的函数:

import { fakeAsync, tick as _tick } from '@angular/core/testing';
import { asyncScheduler, of, timer } from 'rxjs';
import { delay } from 'rxjs/operators';

describe('fakeAsync and RxJS', () => {

  let tick: (milliseconds: number) => void;

  beforeEach(() => {
    let fakeNow = 0;
    tick = milliseconds => {
      fakeNow += milliseconds;
      _tick(milliseconds);
    };
    asyncScheduler.now = () => fakeNow;
  });

  it('should support timer with fakeAsync', fakeAsync(() => {
    const source = timer(100);
    let received: number | undefined;
    source.subscribe(value => received = value);
    tick(50);
    expect(received).not.toBeDefined();
    tick(50);
    expect(received).toBe(0);
  }));

  it('should support delay with fakeAsync', fakeAsync(() => {
    const source = of(0).pipe(delay(100));
    let received: number | undefined;
    source.subscribe(value => received = value);
    tick(50);
    expect(received).not.toBeDefined();
    tick(50);
    expect(received).toBe(0);
  }));

  afterEach(() => {
    delete asyncScheduler.now;
  });
});

其实是因为依靠fakeAsync为了模拟基于时间的可观察到的可能是有用的,我添加了一个fakeSchedulers对我的功能rxjs-marbles包裹。看fake-spec.ts例如用法。

实现与上面的代码片段基本相同 - 只是封装在一个函数中。


自从写下这个答案并添加fakeSchedulers to rxjs-marbles,我写过一篇关于使用假时间进行测试.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何模拟 RxJs 6 计时器? 的相关文章

随机推荐

  • 如何将html5输入类型日期和时间转换为javascript日期时间

    我正在使用 html5 输入类型 日期和时间 如何将表单输入类型转换为javascript对象日期 其中包含时间 这是我的代码的一部分
  • 在 .NET 中使用 XML 注释有哪些优点?

    我无法理解使用 XML 注释的优点 我知道它们可以转换为代码外部的漂亮文档 但使用更简洁的 DOxygen 语法也可以实现同样的效果 我认为 XML 注释是错误的 因为 他们总体上混淆了注释和代码 它们更难被人类阅读 在单个屏幕上可以查看的
  • ggplot2:y 轴标签在绘图区域内左对齐

    我正在寻找一种自动移动 y 轴刻度标签的方法 以便它们显示左对齐within实际地块面积 我喜欢 ggplot 中主题组件的总体灵活性 但在尝试找到通用方法来实现此目的时遇到了困难 我知道给予axis text y的组合hjust 0负右边
  • cmake 是否可以选择避免使用未定义的变量(如 bash set-u)

    Does cmake有一种在使用未定义变量时生成错误的机制 有点像set u选项中bash 我有一个由多个项目组成的大项目CMakeLists txt文件 大约 1500 行 所以使用这种结构是相当困难的 if NOT DEFINED VA
  • 在 Angular 2 中重置模板驱动的表单(模型和验证)

    我们如何重置控件的验证状态模板驱动角度 2 的形式 我知道可以通过设置控件所绑定的模型值来重置控件 但是验证状态 原始 肮脏等 又如何呢 我尝试过这样的事情
  • 有没有办法在 C 中进行柯里化?

    假设我有一个指向函数的指针 stack push stack stk void el 我希望能够打电话curry stack push my stack 并返回一个只需要的函数void el 我想不出一种方法来做到这一点 因为 C 不允许运
  • 重定向时向 Zuul 添加标头

    我正在尝试使用Zuul将调用重定向到其他地方的下游系统 在重定向中 我需要添加一个包含必要数据的标头api接收重定向以进行处理 我似乎无法让下游系统检测到这些数据 附件是我的代码 我在用Zuul from Edgware SR3 Sprin
  • 杀死 Pthread 库中的线程

    I use pthread create thread1 attrs 如果发生某种情况需要杀死这个线程如何杀死它 首先存储线程id pthread create thr 然后稍后打电话 pthread cancel thr 但是 这不是推荐
  • C 中的“由于数据类型范围有限,比较始终为真”警告?

    我有以下代码 Point h define WIDTH 8 define HEIGHT 8 typedef struct Point char x char y Point Board c include
  • 给出 3 个点和一个绘图圆

    我想将点 0 1 1 0 和 0 1 提供给 python 并绘制经过它们的圆 是否存在一个Python模块可以做到这一点 我尝试过使用 matplotlib import matplotlib pyplot as plt plt plot
  • 无法从phonegap中的sd卡读取图像文件:android

    我是一个phonegap新手 我正在尝试使用 Android 中的 SD 卡读取图像文件 PhoneGap官方教程 问题是图像没有显示 而是在其位置出现一个问号 My Code var pictureSource var destinati
  • 使用指针作为容器迭代器是否违反标准

    安吉发表了评论 that a vector使用原始指针作为迭代器类型就可以了 这让我有点困惑 我开始研究它 发现需要vector迭代器只是它们 随机访问迭代器 明确指出指针符合以下条件 指向数组元素的指针满足所有要求 这是编译器提供迭代器的
  • UI-router,在服务中使用stateparams

    我有这样的状态 state admin category url category templateUrl views admin category html resolve category CategoryLoader function
  • ERR背后的实际信号是什么

    我在几个地方 包括SO 读到 e被认为是 糟糕的形式 并且在出现任何错误时退出脚本都是不可靠的 处理错误的更好方法似乎是使用trap 像这样 trap echo there was an error exit 1 ERR 我似乎无法在手册页
  • 转到 C 中的特定地址

    如何 JMP 到 C 中的特定地址 我想用 goto 0x10080000 这不起作用 还有其他方法可以更改程序计数器的地址吗 You can cast函数指针的地址 然后跳转到 void void 0x10008000 为了更清楚一点 t
  • MySQL 中的错误 1064 (42000)

    我正在尝试使用从 MS SQL Azure 数据库创建的数据库转储来填充新的 MySQL 空数据库 但出现以下错误 ERROR 1064 42000 at line 1 您的 SQL 语法有错误 检查与您的 MySQL 服务器版本对应的手册
  • 在 ruby​​ 中运行系统命令并与之交互

    我需要在命令行上运行一个命令来请求用户响应 如果有帮助的话 命令是 gpg recipient Some Name encrypt some file txt 当您运行此命令时 它会发出警告 然后询问 还用这个键吗 是 否 回答 y 让其正
  • 计算预处理器宏

    我有这个宏代码 它允许我定义C枚举和使用一个构造的字符串形式的枚举名称列表 它使我不必重复枚举器名称 并且可能会为大型列表引入错误 define ENUM DEFINITIONS F F 0 Item1 F 5 Item2 F 15 Ite
  • [OVERFLOW:HIDDEN] 的替代方案

    我目前正在我们的系统中工作 我发现很难在 HTML 中使用溢出 请看看我的小提琴 并尝试把 overflow hidden in nav holder background 333333 padding left 30px padding
  • 如何模拟 RxJs 6 计时器?

    我们最近从 Angular 5 更新到 Angular 6 并随之更新为 RxJs 6 作为迁移的一部分 计时器的使用已更改为 Observable timer to timer 在我们的测试中有很多地方我们使用以下模式模拟计时器可观察值