Mocha: Advanced tips to easily test asynchronous fonction

♻ Basic usage

Everyone knows Mocha’s done callack :

it('should work without error', function(done) {
  testedfunction()
    .then(() => done();)
    .catch((err) => done(err); )
  );
});

This is simple, but there’s 2 points to notice here:

    1. I use then(() => done();) and not then(done) : the then(() => {}) form, done is executed with this poiting to Mocha while the other one this is the promise and done may no work.
    2. I use then(…).catch(…) and not then(() => {}, (err)=>{}), here is why:
it('should work without error', function(done) {
  testedFunction()
    .then((result) => {
      assert(result === 'yes'); 
      done(); 
    })
    .catch((err) => done(err); ) 
    // test fails if testedFunction failed or if result != 'yes'
  );
});
it('should work without error', function(done) {
  testedFunction()]
    .then(
      (result) => {
         assert(result === 'yes'); 
         done(); 
       },
       (err) => done(err); ) 
       // test fails if testedFunction failed only. error handler is not called
       // if assert failed
    }
  );
});

♻ Better promise usage:

It is less known that one can return a promise to Mocha:

it('should work without error', function() {
  return testedFunction()
    .then((result) => {
      assert(result === 'yes');
    });
  );
});

♻ Even better: async/await

Since 7.0.0, node support async/await function, and an async function returns a promise “under the hood”, so that we can write tests using aync function:

it('should work without error', async function() {
  const result = await testedFunction();
  assert(result === 'yes');
});

And this is true also for hook functions:

before(async function() {
  await db.connect();
);

 


I use extensively asyn function in my tests: this make my code easier to write, to read and to maintain: so my advice is: try them !


 

See you and have a nice code 🙋

Nodejs & Promise : advanced tips – part two – Using Promise ? Yes, but just any one ;-)

This is the second part of my series dedicated to promise. The previous post, about anti-pattern, is here.


♻ The problem

Let’s say you find a module that fit your need. It returns Q promise while your program use Bluebird promise. Oups… . It probably work, but I’m keen on mixing Pormise implementation, and on being forced to use an implementation I don’t want.

A module should not force the use of a specific kind of promise


♻ A first solution:

Some libraries let users to plug in their favorite promise. Here is an example extract from mongoose documentation:

// Use native promises
mongoose.Promise = global.Promise;
assert.equal(query.exec().constructor, global.Promise);

// Use bluebird
mongoose.Promise = require('bluebird');
assert.equal(query.exec().constructor, require('bluebird'));

This works, but having to plug in a promise for each module (each module having it’s own way to define Promise) is cumbersome.


♻ A better solution: Any-promise.

Here is how any-promise introduces itself:

Let your library support any ES 2015 (ES6) compatible Promise and leave the choice to application authors. The application can optionally register its preferred Promise implementation and it will be exported when requiring any-promise from library code.

The code of the module is straightforward: it get a Promise class from any-promise:

const Promise = require('any-promise');
new Promise(function(resolve, reject){...});

The application then as to register the implementation he wants to use before using any-promise or any mobule depending on it:

require('any-promise/register/bluebird')

Note that any-promise won’t accept to register multiple implementations.


♻ Usage

Numerous modules already depends on any-promise. I regularly use mzthenify-all and fs-promise along with Bluebird. You can also have a look to my own module: events-to-any-promise.


This conclue my posts about Promise. I hope you’ll think to it when you’ll write your public module.

See you and have a nice code 🙋

Nodejs & Promise : advanced tips – part one – Anti-pattern

Here is the first part of a two parts-post dedicated to promise. This part is about some anti-patterns that we ofen use when we begin to play with promise. The second part explains how writing code able to use any promise implementation.


♻ Promise hell

While promise are made to avoid callbak hell, it still possible to see such code:

'use strict';

function doSomethingAsync1() { return Promise.resolve(); }
function doSomethingAsync2() { return Promise.resolve(); }
function doSomethingAsync3() { return Promise.resolve(); }
function doSomethingAsync4() { return Promise.resolve(); }

doSomethingAsync1().then((result1)=>{
  return doSomethingAsync2(result1).then((result2) => {
    return doSomethingAsync3(result2).then((result3)=> {
      return doSomethingAsync4(result3).then((result4) => {
        console.log(result4);
      });
    });
  });
}, (err) => {
  console.log(err);
});

Each result variable is accessible from inner code and thus is error prone, while with promise it’s easy to avoid this:

'use strict';

doSomethingAsync1().then((result)=> {
  return doSomethingAsync2(result);
}).then((result) => {
  return doSomethingAsync3(result);
}).then((result) => {
  return doSomethingAsync4(result);
}).then((result) => { 
  console.log(result); 
},(err) => { 
  console.log(err); 
});

With the ‘short arrow notation’ these becomes:

'use strict';

doSomethingAsync1().then(result => 
  doSomethingAsync2(result)
).then(result => {
  doSomethingAsync3(result)
}).then(result => {
  doSomethingAsync4(result)
}).then(result => { 
  console.log(result); 
},(err) => { 
  console.log(err); 
});

♻ Partial error management

Can you say if one of this two codes is better ?

const somethingAsync = Promise.resolve('foo');
somethingAsync.then( 
  (result) => { 
    // Processing result 
   }, (err) => { 
   // error management 
   });
somethingAsync
  .then((result) => {
    // Processing result
  })
  .catch((err) => { 
    // error management 
  });

The first code handle ‘somethingAsync’ errors only. It does nothing if  ‘Processing result’ failed because the error handler passed in ‘then’ covers only the promise returns by aysnc code.

The second code handle both ‘somethingAsync’ and ‘Processing result’ errors, thanks to promise chaining. If proccesing result throws an error, ‘then’ returns a rejected promise and therefore catch is called. Thus the code snippet at the end of the previous chapter is better like this:

doSomethingAsync1()
.then(result => 
  doSomethingAsync2(result)
).then(result => {
  doSomethingAsync3(result)
}).then(result => {
  doSomethingAsync4(result)
}).then(result => { 
  console.log(result); 
}).catch((err) => { 
  console.log(err); 
});

Bluebirdjs’ wiki has another way of explaining this.

♻ Error is not reject

A function can have a synchronous action to do before calling an asynchronous function:

function foo() {
  let result = doSomethingSync();
  return doSomethingAsync(result);
}

Such code has a huge pitfall. Typically one will use it this like:

foo().then(....);

What’s wrong with this ?
If the synchronous code throw an error, nothing can catch it…

A safer approach consist of writing async function so that all errors are delivered through a promise rejection. Here is a better exemple:

  function foo() {
    try {
      let result = doSomethingSync();
      return doSomethingAsync(result);
    } catch (err) {
      return Promise.reject(err);
    }
  }
}

I’m a fan of  bluebirdjs, which offer a mean to easily turn  an error into a rejection:

const Promise = require('bluebird');

function foo() {
  return Promise.try(() => {
    let result = doSomethingSync();
    return doSomethingAsync(result);
  });
}

This concludes this post. If you don’t know bluebirdjs yet I advise you to have look at it, as far as I know it’s the best promise implementation in Node world (let me know if there’s lib that can compet with). My next post about promise will be issued in a couple of weeks.

See you and have a nice code 🙋