Testing a multitude of data asynchronously in Mocha Testing a multitude of data asynchronously in Mocha mongoose mongoose

Testing a multitude of data asynchronously in Mocha


You can use the async utility library to simplify do an asynchronous loop.

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

The first function is called on each element in the array, it takes two arguments: the item from the array, and a callback function. If the callback receives an error, it immediately goes stops iterating. Once all of the items in the array are done (or any of them return an error), the final function is called. In this example it'll either throw an error or run the Mocha done function.

The readme for async has a good explanation of how the forEach function works.


If your user.validate function is asynchronous, your forEach call will not wait the callback call of user.validate.

Which mean that your forEach function will end before user.validate calls all callbacks and will call done() before every validation has ended.

You should use all parameters of forEach function and call done() in the user.validate callback. I will add one count variable to count callback called and know when I need to call done() function.

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

This should work better. I didn't tested it, but it should work.

PS: Please do not forget semicolons. It can brings you undefined behavior in some cases and it's a bad habbits to not put them (we are programmers !).

EDIT - 08/06/13: Just read something about semicolons in Javascript and remembered about this thread, this is why you should put semicolons in your code : http://bonsaiden.github.io/JavaScript-Garden/#core.semicolon