Как ждать функцию обратного вызова в модульном тесте angular6 + (жасмин + карма) - PullRequest
0 голосов
/ 24 февраля 2020

Обновление:

Кажется, проблема с FileReader. Нашел эту ссылку

Может кто-нибудь подсказать, как мне написать модульный тест для вещи, связанной с FileReader


У меня есть экземпляр, где у меня есть обратный вызов внутри наблюдаемого обратного вызова подписки.

Component.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;
}

component.spe c .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

Ответы [ 2 ]

0 голосов
/ 24 февраля 2020

Измените 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();
});
0 голосов
/ 24 февраля 2020

Ваш тест может работать должным образом, если вы замените tick() на flush(), поскольку callback вложено в вызов subscribe().

flush имитирует асинхронное прохождение времени для таймеров в зоне fakeAsync путем опустошения очереди макросов до тех пор, пока она не станет пустой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...