Rxjs 间隔时 Jasmine Angular 超时

问题描述 投票:0回答:2

我正在做一个简单的冥想应用程序,我使用 rxjs 间隔来计算呼吸/呼气持续时间。这是代码的一部分:

import { AudioService } from './../../services/audio/audio.service';
import { Router } from '@angular/router';
import { MeditateDataService } from './../../services/meditate-data/meditate-data.service';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { interval, Observable, Subscription } from 'rxjs';
import { Haptics, ImpactStyle } from '@capacitor/haptics';

@Component({
  selector: 'app-meditate',
  templateUrl: './meditate.page.html',
  styleUrls: ['./meditate.page.scss'],
})
export class MeditatePage implements OnInit, OnDestroy, OnInit {
  breath_text: String = "Breathe in";
  reset_to_five = 0;
  total_time = 0;
  breath_interval: Subscription;
  time_left = this.meditate.meditate_params.duration * 60 - this.total_time;

  constructor(public meditate: MeditateDataService, public router: Router, public audio: AudioService) {
    this.breath_interval = interval(1000).subscribe(() => {
      this.everySecond();
    });
  }

  ngOnInit() {
    if (this.meditate.meditate_params.enabled_music) {
      this.audio.play_music();
    }
  }

  ngOnDestroy() {
    this.breath_interval.unsubscribe();
    if (this.meditate.meditate_params.enabled_music) {
      this.audio.sounds.music.audio.pause();
      this.audio.sounds.music.audio.currentTime = 0;
    }
    if (this.meditate.meditate_params.enabled_gong) {
      this.audio.sounds.gong.audio.pause();
    }
  }

  toggle_BreathText() {
    if (this.breath_text == "Breathe in") {
      this.breath_text = "Breathe out";
    } else {
      this.breath_text = "Breathe in";
    }
  }

  everySecond() {
    if (this.total_time >= (this.meditate.meditate_params.duration * 60)) {
      this.router.navigateByUrl('/home');
    }
    this.reset_to_five++;
    this.total_time++;
    this.time_left = this.meditate.meditate_params.duration * 60 - this.total_time;
    if (this.reset_to_five == 5) {
      if (this.meditate.meditate_params.enabled_vibrations) {
        Haptics.impact({ style: ImpactStyle.Light });
      }
      if (this.meditate.meditate_params.enabled_gong) {
        this.audio.play_gong();
      }
      this.reset_to_five = 0;
      this.toggle_BreathText();
    }
  }
}

但是当 ng 测试时: MeditatePage > 应该创建 错误:超时 - 异步功能未在 5000 毫秒内完成(由 jasmine.DEFAULT_TIMEOUT_INTERVAL 设置) 在

我尝试了我在网上看到的所有内容,删除应该创建的单元测试,尝试检测 jasmine 是否没有间隔?,增加 jasmine 超时,使用 done(),但我从来没有成功......

angular unit-testing jasmine timeout
2个回答
0
投票

在 Jasmine 中测试使用 RxJS

interval
的代码时,有时测试会在间隔完成之前超时,导致测试失败。要解决此问题,您可以使用 Angular 测试实用程序提供的
fakeAsync
函数,它允许您控制测试中的时间流逝。

这是一个示例,说明如何修改测试以使用

fakeAsync

import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { MeditatePage } from './meditate.page';

describe('MeditatePage', () => {
  let component: MeditatePage;
  let fixture: ComponentFixture<MeditatePage>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ MeditatePage ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(MeditatePage);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should toggle breath text every 5 seconds', fakeAsync(() => {
    spyOn(component, 'toggle_BreathText');
    expect(component.toggle_BreathText).not.toHaveBeenCalled();

    // Simulate 20 seconds passing
    tick(20000);

    expect(component.toggle_BreathText).toHaveBeenCalledTimes(4);
  }));
});

在上面的例子中,我们使用

fakeAsync
来模拟时间的流逝。
tick
函数用于将时钟提前指定的毫秒数。我们正在使用
spyOn
监视 toggle_BreathText 函数以验证它每 5 秒调用一次。
expect
之后的
tick
语句检查该函数在模拟 20 秒的时间后被调用了 4 次。

请注意,仅建议在短时间间隔(例如少于几秒)时使用

fakeAsync
。对于更长的间隔,您可能需要使用
jasmine.clock()
来控制时钟时间。


-1
投票

你的班级似乎没有实现

OnDestroy
。所以
ngOnDestroy
不打电话。

© www.soinside.com 2019 - 2024. All rights reserved.