首页 > 解决方案 > 即使测试没有返回承诺,qunit 如何知道异步测试回调何时完成?

问题描述

Qunit 一个一个地执行异步测试,但是它怎么知道测试已经完成,因为测试没有返回一个 qunit 可以等待的 Promise?

在这个演示示例中https://jsfiddle.net/6bnLmyof/

function squareAfter1Second(x) {
    const timeout = x * 1000;
    console.log("squareAfter1Second x:", x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(x * x);
        }, timeout);
    });
}

const { test } = QUnit;

test( "an async test", async t => {
    console.log("starting test1");
    t.equal( await squareAfter1Second(3), 9 );
    t.equal( await squareAfter1Second(4), 16 );
});

test( "an async test2", async t => {
    console.log("starting test2");
    t.equal( await squareAfter1Second(1), 1 );
});

有 2 个异步测试一个一个地运行。测试将宏任务 (setTimeout) 发布到事件循环,但不知何故 qunit 能够等待测试完成,尽管测试没有返回承诺。此外,在qunit的源代码中,没有 await 关键字。

标签: javascriptes6-promisequnit

解决方案


异步函数总是返回 Promises,一旦到达其块的末尾(或return到达 a),该 Promises 就会解决。因此,即使没有显式返回任何内容,awaits 也意味着两个异步回调都隐式返回 Promises,该 Promisesawait在函数中的所有 s 完成后解析。所以test只需要遍历每个调用它的回调函数,以及await每次调用。

这是一个示例,说明您也可以自己实现此功能,而无需更改任何内部代码squareAfter1Secondtest调用:

const queue = []
const test = (_, callback) => {
  queue.push(callback);
};

function squareAfter1Second(x) {
    const timeout = x * 1000;
    console.log("squareAfter1Second x:", x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(x * x);
        }, timeout);
    });
}

test( "an async test", async t => {
    console.log("starting test1");
    t.equal( await squareAfter1Second(3), 9 );
    t.equal( await squareAfter1Second(4), 16 );
});

test( "an async test2", async t => {
    console.log("starting test2");
    t.equal( await squareAfter1Second(1), 1 );
});

(async () => {
  for (const callback of queue) {
    console.log('Awaiting callback...');
    await callback({ equal: () => void 0 });
    console.log('Callback done');
  }
})();


推荐阅读