在Mocha中异步测试大量数据

时间:2013-02-02 14:06:58

标签: node.js unit-testing testing mongoose mocha

我需要遍历电子邮件列表并检查它们是否有效。如果一个人无法验证,我会抛出一个错误让Mocha知道它。

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()
})

但是,此代码似乎无法正常工作 - 只有数组中的最后一封电子邮件无效才会失效。

我做错了什么?

2 个答案:

答案 0 :(得分:3)

您可以使用 async 实用程序库来简化异步循环。

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()
  })
})

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

readme for async很好地解释了forEach函数的工作原理。

答案 1 :(得分:1)

如果您的user.validate函数是异步的,那么forEach调用将不会等待user.validate的回调调用。

这意味着你的forEach函数会在user.validate调用所有回调之前结束,并会在每次验证结束前调用done()

您应该使用forEach函数的所有参数,并在done()回调中调用user.validate。我将添加一个计数变量来计算所调用的回调,并知道何时需要调用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();
    });

  });

})

这应该更好。我没有测试它,但它应该可以工作。

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

编辑 - 08/06/13 :刚刚在Javascript中阅读有关分号的内容并记住了这个帖子,这就是为什么你应该在你的代码中添加分号:http://bonsaiden.github.io/JavaScript-Garden/#core.semicolon