在Mocha中asynchronoustesting大量数据

我需要通过电子邮件列表循环,并检查他们validation。 如果一个人不能确认,我会抛出一个错误让摩卡知道。

it('validates valid email addresses', function (done) { [ 'oliverash@me.com', 'oliver.ash@me.com', 'oliver-ash@me.com', 'oliver+ash@me.com', 'oliver\'s-email@me.com' ].forEach(function (value) { user.email = value user.validate(function (err) { // Failed to validate, throw an error if (err) { throw new Error() } }) }) // All documents validated, so call `done` done() }) 

但是,这个代码似乎并不正确,只有数组中的最后一封电子邮件无效时才会失效。

我究竟做错了什么?

您可以使用asynchronous实用程序库来简化asynchronous循环。

 it('validates valid email addresses', function (done) { async.forEach([ 'oliverash@me.com', 'oliver.ash@me.com', 'oliver-ash@me.com', 'oliver+ash@me.com', 'oliver\'s-email@me.com' ], function (value, callback) { user.email = value user.validate(callback) }, function (err) { if (err) { throw new Error() } done() }) }) 

第一个函数在数组中的每个元素上被调用,它有两个参数:数组中的项和一个callback函数。 如果callback接收到错误,则立即停止迭代。 一旦数组中的所有项目都完成(或者其中任何一个返回错误),就调用最终的函数。 在这个例子中,它会抛出一个错误或运行摩卡完成function。

async的自述文件很好地解释了forEach函数的工作原理。

如果你的user.validate函数是asynchronous的,你的forEach调用将不会等待user.validate的callbackuser.validate

这意味着您的forEach函数将在user.validate调用所有callback之前结束,并且在每次validation结束之前调用done()

您应该使用forEach函数的所有参数,并在user.validatecallback中调用done() 。 我将添加一个计数variables来计算被调用的callback,并知道何时需要调用done()函数。

 it('validates valid email addresses', function (done) { var count = 0; // count variable [ 'oliverash@me.com', 'oliver.ash@me.com', 'oliver-ash@me.com', 'oliver+ash@me.com', 'oliver\'s-email@me.com' ].forEach(function (value, index, array) { user.email = value; user.validate(function (err) { ++count; // Callback called, we add +1 to count. if (err) { throw new Error(); } // Check if all callbacks have been called and call done if true. if (count === array.length) done(); }); }); }) 

这应该会更好。 我没有testing它,但它应该工作。

PS:请不要忘记分号。 在某些情况下,它会给你带来不确定的行为,不要把它们放在一边(我们是程序员!)。

编辑 – 08/06/13 :刚刚读了一些关于Javascript的分号,并记住这个线程,这就是为什么你应该把分号放在你的代码: http : //bonsaiden.github.io/JavaScript-Garden/#core.semicolon