代码之家  ›  专栏  ›  技术社区  ›  TheUnreal

因果报应茉莉花改用承诺后不要嘲笑服务方法

  •  0
  • TheUnreal  · 技术社区  · 5 年前

    我有一个调用服务方法的组件。 当服务方法返回一个可观察的结果时,它工作得很好, 但当我把它改成“承诺”时,测试开始失败。

    测试中的变化是:

    工作:

    测试:

    const getPackListSpy = ppackService.listPacks.and.returnValue( of(packListResult) );
    
    it('should show pack list', fakeAsync(() => {
          fixture.detectChanges();
          tick(5000);
          fixture.detectChanges();
          const packsInView = fixture.nativeElement.querySelectorAll('.packName').length;
    
          expect(packsInView).toBe(2);
        }));
    

    组成部分:

    this.protocolPackService.listPacks()
          .subscribe((packs) => {
            this.packs = packs;
          });
    

    改为承诺后不工作:

    测试:

    const getPackListSpy = ppackService.listPacks.and.returnValue( Promise.resolve(packListResult) );
    

    组成部分:

    this.packs = await this.protocolPackService.listPacks();
    

    问题是,我在模板中的项目列表没有显示任何数据(基于 this.packs )在变成承诺之后。在测试环境之外的两种情况下,组件都可以正常工作。

    知道哪里出了问题吗?

    组件代码:

    ngOnInit() {
        this.getUploadedPacks();
     }
    
      async getUploadedPacks() {
        const packs = await this.protocolPackService.listPacks();
        this.packs = [{
          name: 'pack'
         }];
        this.packs = this.packs.concat(packs);
       }
    

    服务:

    listPacks(): Promise<any> {
        return this.http.get('packs').toPromise();
      }
    
    0 回复  |  直到 5 年前
        1
  •  0
  •   shohrukh    5 年前

    例如,必须使用一些方法来测试异步代码 fakeAsync/tick from angular 测试库:

    it('should show items', fakeAsync(() => {
      const { comp, el, fixture } = setup();
    
      fixture.detectChanges();
      tick(1000);
      fixture.detectChanges();
    
      expect(comp.packs.length).toBe(2);
    }));
    

    看看这个 live demo on stackblitz.

    p、 问题是,当你用rxjs模拟你的服务方法时 of 操作员,它将像同步代码一样工作,例如:

    console.log(1);
    of(2).subscribe(v => console.log(v));
    console.log(3);
    

    这段代码将用于控制台。日志:1,2,3。

    但当您使用Promise时,它的行为将类似于异步代码,例如:

    console.log(1);
    Promise.resolve(2).then(v => console.log(v));
    console.log(3);
    

    这段代码将用于控制台。日志:1,3,2。

    这就是为什么在使用承诺模拟服务方法的情况下,您必须编写单元测试,记住您正在处理异步代码。