首页 > 解决方案 > 为什么茉莉不等我的承诺完成?

问题描述

我正在使用 FileSystem API 生成一个目录,其中包含 2 个条目,我需要将其用作要运行的测试的输入。问题是 Jasmine 在运行测试之前没有等待承诺解决,所以它失败了。我使用了异步包装器,但似乎没有什么不同。

有谁知道它为什么失败?

describe('traverseDirectory() method', () => {

let directoryToTraverse;
let entries;

beforeEach(async(() => {

    console.log('beforeEach test');


    const file1 = createBlob(['<a id="a"><b id="b">Hello A</b></a>'], {type: 'text/html'});
    const file2 = createBlob(['<a id="b"><b id="b">Hello B</b></a>'], {type: 'text/html'});

    function createFile(fs: any, fileName: string, blob: Blob): Promise<any> {

      return new Promise((resolve, reject) => {

        fs.root.getFile(fileName, {create: true}, (fileEntry) => {

          fileEntry.createWriter((fileWriter) => {
            fileWriter.onwriteend = (e) => {
              resolve(fileEntry);
              // @ts-ignore
            };

            fileWriter.write(blob);
          });
        });
      });
    }

    function moveToDirectory(directoryEntry: any, fileEntry: any): void {
      fileEntry.moveTo(directoryEntry);
    }

    function createDirectory(fs: any, name: string): Promise<any> {
      return new Promise((resolve, reject) => {
        fs.root.getDirectory(name, {create: true}, (directoryEntry) => {
          resolve(directoryEntry);
        }, errorHandler);
      });

    }


    function errorHandler(err: any): void {
      console.log('ERROR:', err);
    }


    const promise = new Promise((resolve, reject) => {

      function onInitFs(fs: any): void {
        createDirectory(fs, 'Documents').then((directoryEntry) => {

          const f1 = createFile(fs, 'File1.html', file1);
          const f2 = createFile(fs, 'File2.html', file2);
          Promise.all([f1, f2]).then((createdEntries) => {
            createdEntries.forEach((entry) => {
              moveToDirectory(directoryEntry, entry);

            });
            directoryToTraverse = directoryEntry;
            console.log('Finished setup');
            resolve();
          });
        });

      }

      // @ts-ignore
      window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024, onInitFs, errorHandler);

    });

  })
);

it('should run', async(() => {

  console.log('Running the test');
  service.traverseDirectory(directoryToTraverse).then(res => {
    entries = res;
  });

  expect(directoryToTraverse).toEqual(entries);


}));

});

标签: angulartypescriptpromisejasmine

解决方案


https://www.digitalocean.com/community/tutorials/angular-testing-async-fakeasync

当所有承诺都解决后,您可以使用fixture.whenStablefor 然后继续测试,但我认为在您的情况下,您应该将期望放在 then 中,因为由于 Promise 的异步性质,期望将在 then 内部发生的事情之前运行。

it('should run', async(() => {

  console.log('Running the test');
  service.traverseDirectory(directoryToTraverse).then(res => {
    entries = res;
    console.log(entries); // make sure you see this line
    expect(directoryToTraverse).toEqual(entries);
  });
}));

推荐阅读