如何测试角度-catchError运算符'rxjs'

如何解决如何测试角度-catchError运算符'rxjs'

enter image description here

能帮我测试一下代码吗?我无法测试可观察间隔(1000)的管道内的catchError运算符...

我不知道对整数(1000)的可观察角度进行多少单位测试。我需要模拟一个间隔的执行,并模拟错误。我没有执行代码,代码已经完成,我是新员工,我被分配了执行单元测试的任务。我不知道是否有必要在一定间隔内捕获Error。

我的文件ts是:

import { Injectable,EventEmitter } from '@angular/core';
import {Subscription,Observable,interval,BehaviorSubject,throwError} from 'rxjs';
import {take,map,catchError,finalize} from 'rxjs/operators';
import { environment } from 'environments/environment';

/**
 * @Class CounterSessionProvider
 * @description This class is a provider for control session time
 * @author Andres Giraldo Londoño,Pragma S.A.
 */
@Injectable({
  providedIn: 'root',})
export class CounterSessionProvider {
  // 4 minutes
  public inactivityTime = 20; // environment.inactivityTime; // environment.inactivityTime -> 20 seconds
  counterStateEmitter = new EventEmitter();
  currentSubscription: Subscription;
  public substracCounter$: BehaviorSubject<boolean>;

  constructor() {
    this.substracCounter$ = new BehaviorSubject(false);
  }

  public start() {
    this.currentSubscription = this.initInterval().subscribe();
  }

  public initInterval(): Observable<number> {
    return interval(1000).pipe(
      take(this.inactivityTime),map((index: number) => this.inactivityTime - (index + 1)),catchError(err => {
        this.counterStateEmitter.error(err);
        return throwError(err);
      })
    );
  }

  public restarCounterTime(): void {
    this.substracCounter$.next(true);
  }

  public stop() {
    if (this.currentSubscription) {
      this.currentSubscription.unsubscribe();
    }
    this.counterStateEmitter.emit('ABORTED');
  }
}

我的文件规范是:

import {fakeAsync,TestBed,tick} from '@angular/core/testing';
import { CounterSessionProvider } from './counter-session.provider';
import {interval,Subscription,throwError} from 'rxjs';
import {catchError,take} from 'rxjs/operators';
import { TestScheduler } from 'rxjs/testing';

describe('CounterSessionProvider',() => {
  let counterSessionProvider: CounterSessionProvider;
  let scheduler: TestScheduler;

  beforeEach(() => {
    counterSessionProvider = new CounterSessionProvider();
  });

  /*beforeEach(() => {
    scheduler = new TestScheduler((actual,expected) => {
      expect(actual).toEqual(expected);
    });
  });*/

  /*it('should throw error when initInterval interval',fakeAsync(() => {
    scheduler.run(helpers => {
      spyOn(counterSessionProvider,'initInterval').and.returnValue(throwError('ERROR'));
      const actions$ = helpers.hot('--a',{ a: 1000 });
      const completion$ = helpers.cold('--c',{ c: 1000 });
      expect(counterSessionProvider.initInterval).toBe(completion$);
    });
  }));*/

  it('should initialize currentSubscription from interval',fakeAsync(() => {
    let currentVal = null;
    const numberObservable = counterSessionProvider.initInterval();
    counterSessionProvider.currentSubscription = numberObservable.subscribe((value: number) => {
      currentVal = value;
    });
    tick(1000);
    expect(currentVal).toEqual(19);
    counterSessionProvider.currentSubscription.unsubscribe();
  }));

  it('should emit a String COMPLETE when start() is called',() => {
    spyOn(counterSessionProvider,'start');
    counterSessionProvider.start();
    counterSessionProvider.counterStateEmitter.subscribe(value => {
      expect(value).toEqual('COMPLETE');
    });
    expect(counterSessionProvider.start).toHaveBeenCalled();
  });

  it('should call stop()','stop');
    counterSessionProvider.currentSubscription = new Subscription();
    counterSessionProvider.stop();
    counterSessionProvider.counterStateEmitter.subscribe((value: string) => {
      expect(value).toEqual('ABORTED');
    });
    expect(counterSessionProvider.stop).toHaveBeenCalled();
  });

  it('should call method start and initilize currentSubscription',fakeAsync(() => {
    counterSessionProvider.start();
    tick(1000);
    counterSessionProvider.currentSubscription.unsubscribe();
    expect(counterSessionProvider.currentSubscription).not.toBeNull();
  }));

  it('should call restarCounterTime() and emit a TRUE',() => {
    counterSessionProvider.restarCounterTime();
    counterSessionProvider.substracCounter$.subscribe(value => expect(value).toBeTruthy());
  });

  it('should call method stop and emit ABORTED',fakeAsync(() => {
    counterSessionProvider.start();
    tick(1000);
    counterSessionProvider.stop();
  }));

  /*beforeEach(() => {
    counterSessionProvider = TestBed.get(CounterSessionProvider);
  });

  it('should be created',() => {
    expect(counterSessionProvider).toBeTruthy();
  });

  it('should return ABORTED when stop function is called',() => {
    counterSessionProvider.start();
    counterSessionProvider.counterState.subscribe((msg: string) => {
      expect(msg).toEqual('ABORTED');
    });
    counterSessionProvider.stop();
  });*/
});

但是我需要涵盖您所涵盖的所有代码。在下图中,我显示了我需要的覆盖范围。

尝试应用Shashank Vivek给我的建议,结果如下:

enter image description here

解决方法

这就是我的建议,throw代表catchError,类似demo的事物,否则将不会调用catchError。我不确定是否应该删除catchError,您应该与团队确认(因为其中似乎包含一些代码)

component.ts

  public initInterval(): Observable<number> {
    return interval(1000).pipe(
      take(this.inactivityTime),map((index: number) => {
        // write some condition to "throw" otherwise "catchError" is of now use
        if (this.inactivityTime > 30) {
          throw new Error('inactivityTime greater than 30');
        }
        return this.inactivityTime - (index + 1);
      }),catchError((err) => {
        this.counterStateEmitter.error(err);
        return throwError(err);
      }),finalize(() => {
        this.currentSubscription.unsubscribe();
        this.counterStateEmitter.emit('COMPLETE');
      })
    );
  }

然后 spec.ts ,您设置了引发错误的条件:

  it('should handle error in initInterval',fakeAsync(() => {
    let currentVal;
    let someError;
    spyOn(
      counterSessionProvider.counterStateEmitter,'error'
    ).and.callThrough();
    counterSessionProvider.inactivityTime = 35; // just to simulate the error event as per the code I have added
    const numberObservable = counterSessionProvider.initInterval();
    counterSessionProvider.currentSubscription = numberObservable.subscribe(
      (value: number) => {
        currentVal = value;
      },(err) => {
        someError = err;
      }
    );
    tick(1000);
    expect(currentVal).toBeUndefined();
    expect(someError).toBeDefined(); // you can also use .toBe('inactivityTime greater than 30')
    expect(counterSessionProvider.counterStateEmitter.error).toHaveBeenCalled();
    counterSessionProvider.currentSubscription.unsubscribe();
  }));

尝试一下,让我知道是否可行。

封面截图: enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-