jasmine - 如何在茉莉花测试中模拟 RXJS timer()?
问题描述
我有一个角度组件来轮询新数据,当我们等待响应时,它每 X 秒更新一次 UI 中的消息。它循环显示一个简单的消息字符串数组。
一旦收到正确的数据,我们就会导航到相应的页面。
this.pollSubscription = timer(0, pollTimeInSeconds)
.pipe(
//convert each observable iteration into an interval in seconds
map((count: number) => count * pollTimeInSeconds),
//keep going if we are below the max poll time
takeWhile((time: number) => time < this.maxPollTime),
//update the UI message
tap((time: number) => this.updateCurrentMessage(time)),
//
switchMap(() => this.getDataOrError$())
)
.subscribe(
//navigate to the correct page
(d: IData) => this.navigateBasedOnStatus(d),
//If an error occurs, OR the observable completes (which should not happen), navigate to the error page
() => this.navigateToError(),
() => this.navigateToError()
);
我想测试这种行为,但我不完全确定如何模拟timer
这种情况。我看到了这个 SO 答案,但我无法根据我的情况来解决这个问题。
理想情况下,我想构建一个类似这样的测试,以确保显示每条消息,并且如果计时器比预期的时间长,它会循环回到第一条消息:
it('should show every status as the timer changes', fakeAsync(() => {
tick(0);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message one');
tick(1000);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message two');
tick(2000);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message three');
//etc...
}));
编辑我正在根据下面的一些评论进行新的测试尝试,但这仍然不起作用
let timerTick: (milliseconds: number) => void;
beforeEach(() => {
let fakeNow = 0;
timerTick = (milliseconds: number): void => {
fakeNow += milliseconds;
tick(milliseconds);
};
asyncScheduler.now = (): number => fakeNow;
});
afterEach(() => {
delete asyncScheduler.now;
});
it('should show every status as the timer changes', fakeAsync(() => {
fixture.detectChanges(); // triggers ngOnInit()
const pollTimeInSeconds = loginPollTime * 1000;
let received: number | undefined;
timer(0, pollTimeInSeconds, asyncScheduler).subscribe((value: number) => received = value);
console.log(received);
timerTick(0);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message one');
console.log(received)
timerTick(pollTimeInSeconds);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message two');
console.log(received)
timerTick(pollTimeInSeconds * 2);
fixture.detectChanges();
expect(debugEl.nativeElement.innerText.trim()).toEqual('Message three');
console.log(received)
}));
茉莉花输出是:
Expected 'Message one' to equal 'Message two'.
Expected 'Message one' to equal 'Message three'.
控制台输出为:
> undefined
> 0
> 1
> 3
解决方案
推荐阅读
- ruby-on-rails - 视图中的 textNode 来自哪里?
- javascript - 从 ID 获取值并使用 javascript 插入输入
- javascript - “TypeError:props.todos.map 不是函数”无法弄清楚原因是什么?
- javascript - 如何在 html 画布弧中从 startAngle 和 endAngle 找到更小的角度?
- unity3d - LGSVL AssetBundles 文件长度为零
- javascript - 选择下拉值使用 jquery 更改文本字段值
- c++ - CMake - 新的 Boost 版本可能有不正确或缺少的依赖项并导入
- json - 将静态行插入json
- python - 如何在 Python 中比较两个列表中的值?
- linux - 如何使用单个命令获取 CPU、RAM 和 DISK