angular中delaydebounceTime等时间相关操作符单元测试的一种方法

在上篇文章中咱们讲述了如何在angular中的应用弹珠测试来模仿http异步申请。

应用弹珠测试的办法尽管很官网很正统,但因为其调度器的失效周期的设置起因,若要在单元测试中联合fixture.detectChanges();在某个测试用例结束后持续与组件进行交互,则会产生No test scheduler initialized!错语。

在单元测试中手动的与组件进行交互虽不正规,但该计划无疑会让新成员感触到单元测试敌对性的一面,升高对其的排挤水平。

sample

比方以后有一组件的性能是当用户在input中输出相应的内容时,先应用500ms防抖阻止冗余的申请,在进行后盾的模仿异步申请:

组件相干代码:

    // 当输出发生变化时,500ms稳固后从新由后盾拉取数据
    this.input.valueChanges.pipe(
      debounceTime(500),
      distinctUntilChanged(),
      switchMap(value => {
        this.tagName = value;
        
        // 申请后盾
        return this.tagService.findTop20ByCourseAndNameLike(this.state.courseId, value);
      })
    ).subscribe((tags: Array<Tag>) => {
      this.tags = tags;
    });

应用弹珠测试的服务层tagService相干代码:

  /**
   * 模仿实在后盾,异步返回数据
   */
  public findTop20ByCourseAndNameLike(courseId: number, name: string): Observable<Array<Tag>> {
    Assert.notNull(courseId, '课程ID未定义');

    const tags = new Array<Tag>();
    for (let i = 0; i < 20; i++) {
      tags.push(new Tag({
        id: randomNumber(),
        name: randomString('name'),
        course: new Course({id: randomNumber()})
      }));
    }
    
    // 应用弹珠测试返回tags
    return cold('---(x|)', {x: tags});
  }

基于上述代码,在单元测试中若仅把单元测试的指标定格为单元测试,则不会有任何问题。

但如果咱们将单元测试的指标扩大为:不启动后盾的前提下,独自疾速开发前台相干组件。那么弹珠测试将无奈满足该需要:

当咱们看到单元测试生成的被测试组件时,总想点击一些功能性的按钮,用“眼睛”来确认本人的程序是正确的 —- 只管咱们晓得这并不是单元测试的正确用法,但却无法控制住本人的好奇心。

  fit('should create', fakeAsync(() => {
    expect(component).toBeTruthy();
    
    // 自动检测组件变动并从新组件渲染
    fixture.autoDetectChanges();
  }));

如上所示,咱们本期待输出某些字符后,cold()办法可能在肯定工夫后返回模仿后盾返回的数据,但却失去了No test scheduler initialized!的谬误。

集体猜测这可能是因为jasmine-marbles设置了无效上下文作用域造成的。

rxjs-marbles

rxjs-marbles提供了一种解决办法:让咱们能够在不应用补丁的状况下,应用tick()办法来模仿一般时钟以及RxJS调度器的工夫推动。

这使得咱们能够摈弃弹珠测试而改用delay的办法来实现异步模仿申请,更重要的:像debounceTime等一些工夫相干的操作符也可能被轻松的模仿。

装置

npm i rxjs-marbles --save-dev

应用

tagService

// 删除原弹珠测试
- return cold('---(x|)', {x: tags});

// 应用of + delay的办法来模仿异步提早申请
+ return of(tags).pipe(delay(500));

单元测试验证

应用tick进行模仿时钟推动:

import {fakeSchedulers} from 'rxjs-marbles/jasmine/angular';

  // fakeSchedulers使咱们能够应用tick()来模仿rxjs中的时钟推动
  it('input change', fakeSchedulers(() => {
    component.tags = [];
    component.input.setValue('hello');

    // 模仿推动第一个防抖
    tick(500);

    // 断言正确的推动了防抖操作符
    expect(component.tagName).toEqual('hello');

    // 断言因为异步delay的作用,组件中的tags未发生变化
    expect(component.tags.length).toEqual(0);

    // 模仿推动tagService中的delay
    tick(500);

    // 断言胜利推动了delay操作符
    expect(component.tags.length).toBeGreaterThan(1);
  }));

组件交互成果

此时,咱们借助此单元测试生成的组件进行一些交互性的测试

本文作者:河北工业大业梦云智开发团队 潘杰

本文由乐趣区整理发布,转载请注明出处,谢谢。

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据