簡體   English   中英

如何在 angular6+ 單元測試中等待回調函數(Jasmine+karma)

[英]How to wait for callback function in angular6+ unit test (Jasmine+karma)


更新:

這似乎是 FileReader 的問題。 找到這個鏈接

誰能建議我如何為 FileReader 相關的事情編寫單元測試


我有一個實例,其中我在 observable 訂閱回調中有回調。

組件.ts

 public ngOnInit(): void {
 this.subscriptions.push(this.route.paramMap.subscribe((params: ParamMap) => {
 this.service.getAttachment()
      .subscribe(response => {
          this.convertBlobToBase46String(response.contentBytes, 
          async (data) => {
              this.fileData = data;
          });
        this.isAttachmentLoadingCompleted = true;
      }, error => {
        this.isAttachmentLoadingCompleted = true;
        this.loggingServie.logError(error, 'Error occurred while fetching attachment.');
      });
 }));
}

 private convertBlobToBase46String(resp, callback) {
         const reader = new FileReader();
         reader.onload = function () {
                        callback(reader.result);
                        };
         reader.readAsDataURL(resp);
    }

public isAttachmentVisible(): boolean {
       if (this.fileData != null && this.isAttachmentLoadingCompleted) {
           return true;
         }

      return false;
}

組件.spec.ts

it('should hide attachment if attachment is not visible', fakeAsync(() => {
  let content = "Hello World";
  let data = new Blob([content], { type: 'text/plain' });
  let arrayOfBlob = new Array<Blob>();
  arrayOfBlob.push(data);
  let file = new File(arrayOfBlob, "Mock.svc");

  spyOn(service, 'getAttachment').and
    .returnValue(Observable.of({ mimeType: 'text/plain', contentBytes: file }));

  component.ngOnInit();
  fixture.detectChanges();
  tick(40);

  const returnValue = component.isAttachmentVisible();

  expect(returnValue).toBe(true);
  }));

這里fileData設置在回調函數中,它在isAttachmentVisible()方法中使用,因此它應該等待回調完成。 但它不會等待它,即使我增加了刻度值,它isAttachmentVisible()在設置fileData之前調用isAttachmentVisible()

如果您將tick()替換為flush()您的測試可能會按預期工作,因為callback嵌套在subscribe()調用中。

flush通過排空宏任務隊列直到它為空來模擬fakeAsync區域中計時器的異步時間流逝。

將您的ngOnInit更改為如下,嵌套subscribes是一種反模式。

public ngOnInit(): void {
  this.subscriptions.push(
    this.route.paramMap.pipe(
     switchMap((params: ParamMap) => this.service.getAttachment()),
   ).subscribe(response => {
      // not sure why the callback is marked as async, nothing async about this
      this.convertBlobToBase465String(response.contentBytes, async data => {
        this.fileData = data;
        // see the bottom log when you run your test
        console.log(this.fileData);
      });
      this.isAttachmentLoadingCompleted = true;
   }, error => {
      this.isAttachmentLoadingCompleted = true;
      this.loggingService.logError(error, 'Error occured while fetching attachment.');
    });
  );
}

public isAttachmentVisible(): boolean {
       if (this.fileData != null && this.isAttachmentLoadingCompleted) {
           console.log('returing true for isAttachmentVisible');
           return true;
         }

      return false;
}

然后將您的測試更改為:

it('should hide scanned image if image is not visible', async(done) => {
  let content = "Hello World";
  let data = new Blob([content], { type: 'text/plain' });
  let arrayOfBlob = new Array<Blob>();
  arrayOfBlob.push(data);
  let file = new File(arrayOfBlob, "Mock.svc");

  spyOn(service, 'getAttachment').and
    .returnValue(Observable.of({ mimeType: 'text/plain', contentBytes: file }));

  component.ngOnInit();
  fixture.detectChanges();
  // fixture.whenStable() waits for promises to complete, maybe you need two of these
  await fixture.whenStable();
  // await fixture.whenStable();
  console.log('fileData: ', component.fileData);
  console.log('isAttachmentLoadingCompleted: ', component.isAttachmentLoadingCompleted);
  // make sure above logs to not null and true, make them public just to see the log then
  // you can set them back to private if you would like.
  const returnValue = component.isAttachmentVisible();

  expect(returnValue).toBe(true);
  done();
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM