在Mochajs中,他们使用“done()”来测试异步代码,如下所示:
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) throw err;
done();
});
});
});
});
这究竟是什么意思?我做了console.log(done.toString()),我得到了这个:
function (err) {
if (err instanceof Error || toString.call(err) === '[object Error]') {
return done(err);
}
if (err) {
if (Object.prototype.toString.call(err) === '[object Object]') {
return done(new Error('done() invoked with non-Error: '
+ JSON.stringify(err)));
}
return done(new Error('done() invoked with non-Error: ' + err));
}
done();
}
这里的done()最后是否与第一段代码中的done()不同?
答案 0 :(得分:18)
Mocha能够处理同步和异步测试。当您运行同步测试时,您可以将其作为匿名函数传递给it
,并且您不必执行任何其他操作:Mocha知道测试在函数返回时结束。但是,如果您正在运行异步测试,则必须告诉Mocha该测试是异步的。有两种方法可以执行此操作:
声明传递给it
的匿名函数接受一个参数。 Mocha将使用单个参数调用您的匿名函数,该函数必须调用以指示您的测试结束。 (由于传统原因,此参数称为done
。您可以将其称为complete
,cb
或platypus
,它可以正常工作。)如果您致电{{1没有值,测试成功。使用值时,测试失败,值应为done
对象或从Error
派生的对象。
返回承诺:Mocha将等待承诺得到解决或拒绝。如果已解决,则测试成功。如果被拒绝,则测试失败。
执行Error
时看到的代码只是Mocha在声明参数时传递给测试的函数的代码。您可以在其中看到我上面提到的一些内容(例如,如果您将参数传递给done.toString()
,则应该是done
或从Error
派生的。 Error
中还有另一个done
函数,它对Mocha是私有的。
答案 1 :(得分:3)
由于node.js的异步性质,你必须告诉Mocha你完成的测试。
对于经典同步语言,您将在方法完成后完成。但是在节点中,首先执行整个方法,然后执行user.save()
的内部主体。
Mocha只是等待测试,直到done()
被调用,因为它没有任何其他选项来查找是否应该执行其他内容或者它已完成。
您拥有的输出只是函数体done
。
答案 2 :(得分:3)
所有测试用例包括before(),after(),beforeEach(),afterEach()必须在最后调用done()告诉mocha所有任务都已完成。
如果缺少done(),则会发生超时异常,因为mocha将等待'done()'直到超时。