8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何在调用 finalize() 之前测试由可观察回调更新的 Angular 组件属性值?

Cem Polat 2月前

63 0

我有一个组件属性,该属性在订阅的可观察对象的下一个方法中更新,表示 http 事件的上传进度。在为此方法编写单元测试时,我希望

我有一个组件属性,它在我订阅的可观察对象的方法中更新 next ,该方法表示 http 事件的上传进度。在为此方法编写单元测试时,我想编写一个测试来检查订阅 http 事件时该属性是否已更新。

我编写的测试是:

it('Should display progress bar', async () => {
    mockFileTransferService.uploadQuarantineFile.and.returnValue(
      of(
        {
          body: ['blodId1'],
          type: 1,
          total: 50,
          loaded: 100,
        },
        {
          body: ['blodId1'],
          type: 1,
          total: 100,
          loaded: 100,
        })
    );
    component.onUpload();
    expect(component.uploadProgress).toBe(NumberConstant.FIFTY);
  });

组件的 onUpload() 方法:

 onUpload() {
    const upload$ = this.fileTransferService.uploadQuarantineFile(this.formData)
      .pipe(
        finalize(() => this.reset())
      );
    // tslint:disable-next-line:no-any
    this.subscription.add(upload$.subscribe((e: any) => {
      if (e.type === HttpEventType.UploadProgress && e.total) {
        this.uploadProgress = Math.round((e.loaded / e.total) * NumberConstant.ONE_HUNDRED);
      }
      if (e.type === HttpEventType.Response) {
        this.messageBarService.openMessageBar(
          MessageBarStatesEnum.success,
          'File Uploaded successfully.',
          ''
        );
      }
    }, (error: HttpErrorResponse) => {
      this.error = true;
      this.errorMessage = error.message;
      this.trackingService.logTrace(error.message);
    }));
  }

我的单元测试由于以下原因失败: Expected 0 to be 50.

看来 finalize() 在我测试组件的 uploadProgress 属性之前该方法就被调用了,因为 this.reset finalize() 方法 uploadProgress 值为 0。

帖子版权声明 1、本帖标题:如何在调用 finalize() 之前测试由可观察回调更新的 Angular 组件属性值?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Cem Polat在本站《typescript》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 编写异步测试可能相当棘手,

    要理解为什么会出现此问题,请理解它源自 uploadQuarantineFile 方法的异步行为、可观察对象发出事件的时间以及 finalize() 运算符的工作方式。如果仔细观察,finalize() 会在可观察对象完成时被调用,它会在测试断言之前运行,将 uploadProgress 重置为 0。我鼓励您在进行测试时使用 fakeAsync tick 尤其是在进行异步调用时,因为 jasmine 使用 async .

    为了避免这种情况,我修改了您的代码以使用它们,希望它有所帮助。

    有关两者的文档请参阅: faskAsync tick

    改变了功能 upload

    import { HttpEventType, HttpErrorResponse } from '@angular/common/http';
    import { finalize } from 'rxjs/operators';
    
    onUpload() {
      const upload$ = this.fileTransferService.uploadQuarantineFile(this.formData).pipe(
        finalize(() => this.reset())
      );
    
      const observer = {
        next: (event: HttpEvent<string[]>) => {
          if (event.type === HttpEventType.UploadProgress && event.total) {
            this.uploadProgress = Math.round((event.loaded / event.total) * NumberConstant.ONE_HUNDRED);
          }
          if (event.type === HttpEventType.Response) {
            this.messageBarService.openMessageBar(
              MessageBarStatesEnum.success,
              'File Uploaded successfully.',
              ''
            );
          }
        },
        error: (error: HttpErrorResponse) => {
          this.error = true;
          this.errorMessage = error.message;
          this.trackingService.logTrace(error.message);
        }
      };
    
      this.subscription.add(upload$.subscribe(observer));
    }
    
    import { fakeAsync, tick } from '@angular/core/testing';
    import { of } from 'rxjs';
    import { HttpEventType } from '@angular/common/http';
    
    describe('UploadComponent', () => {
      let component: UploadComponent;
      let mockFileTransferService: jasmine.SpyObj<FileTransferService>;
    
      beforeEach(() => {
        mockFileTransferService = jasmine.createSpyObj('FileTransferService', ['uploadQuarantineFile']);
        component = new UploadComponent(mockFileTransferService);
      });
    
      it('Should update progress and display success message', fakeAsync(() => {
        const mockUploadEvents = [
          { type: HttpEventType.UploadProgress, loaded: 50, total: 100 },
          { type: HttpEventType.UploadProgress, loaded: 100, total: 100 },
          { type: HttpEventType.Response, body: ['blobId1'] }
        ];
    
        mockFileTransferService.uploadQuarantineFile.and.returnValue(of(...mockUploadEvents));
    
        spyOn(component, 'reset');
        spyOn(component.messageBarService, 'openMessageBar');
    
        component.onUpload();
    
        tick();
        expect(component.uploadProgress).toBe(50);
    
        tick(); 
        expect(component.uploadProgress).toBe(100);
    
        tick(); 
        expect(component.messageBarService.openMessageBar).toHaveBeenCalledWith(
          MessageBarStatesEnum.success,
          'File Uploaded successfully.',
          ''
        );
    
        tick(); 
        expect(component.reset).toHaveBeenCalled();
      }));
    });
    
  • 德里克,我已经按照您提供的方法实现了该方法,现在我发现两个断言都失败了,因为 uploadProgress 在每个期望时仍然设置为 0,我通过在每个期望语句之前记录该值来确认这一点。

  • 抱歉,我忘了在最后一部分打勾,您还可以检查您的方法是否被调用 spyOn(component, 'reset').and.callThrough();

  • 哇,真奇怪,我修改了你的代码,我不知道你如何实现下一个功能,所以我尝试实现我的代码,改变了一些东西,让我们看看会发生什么。我上传了一个新代码,希望它能有所帮助@Rick

返回
作者最近主题: