Promise

Unit.js integrates bluebird for handling asynchronous unit tests.

Bluebird is a fully featured promise library with focus on innovative features and performance.

See the official documentation of bluebird for more details.

A light adjustment was added to write promise with BDD style:

test.promise
  .given(function() {
    // ...
  })
  .when(function() {
    // ...
  })
  .then(function() {
    // ...
  })
;

Usage

test.promise

Bluebird library with two methods added, test.promise.given and test.promise.when.

So, the test.promise object is adapted for BDD style (given, when, then) with promise.

test.promisify()

Shortcut of test.promise.promisify().

test.promisifyAll()

Shortcut of test.promise.promisifyAll().

test.promise.given

Create a promise that is resolved with the given value.

  • If value is already a trusted Promise, it is returned as is.
  • If value is not a thenable, a fulfilled Promise is returned with value as its fulfillment value.
  • If value is a thenable (Promise-like object, like those returned by jQuery's $.ajax), returns a trusted Promise that assimilates the state of the thenable.

Note: Unlike test.promise.resolve(), if the value is a function, test.promise.given() is the equivalent of test.promise.resolve().then(value).

test.promise.when

Just an alias of test.promise.then() for BDD style (given, when, then).

Examples

Promisify the "fs" module:

var fs = test.promisifyAll(require('fs'));

// ...

it('read file async', function(done) {

  fs.readFileAsync('./file.js', 'utf8')

    .then(function(contents){

      test.string(contents);
      done();
    })

    .catch(function(err){
      test.fail(err.message);
    })

    .finally(done)
    .done()
  ;
});

Test a request:

test.$factory('httpRequest', function() {
  return test.promisifyAll(require('request'));
});

describe('HTTP promise', function() {

  it('should connect to Google', function(done) {
    var request = test.$di.get('httpRequest');

    request.getAsync('http://google.com')
      .spread(function (res, body) {
        test
          .number(res.statusCode)
            .is(200)

          .string(body)
            .contains('google')
        ;
      })
      .catch(function (err) {
        test.fail(err.message);
      })
      .finally(done)
      .done();
  });

Note: you can also use httpAgent() to test HTTP requests.

Test an asynchronous function:

it('async function', function(done) {

  test.promise

    .given(anyAsyncFunction())

    .then(function(contents) {

      test.string(contents)
        .contains('some value');
    })

    .catch(function(err){
      test.fail(err.message);
    })

    .finally(done)
    .done()
  ;
});

The .done() method at the end is very important.
Bluebird catches the error and ensures that there are no error which breaks the script execution, this behavior allow to handle the errors (even in the catch method). This is useful if you want to test an error (example with error() or exception())

So with the promises, to be able to rethrow an error, you should add .done() at the end like this:

.catch(function(err){
  test.fail(err.message);
})
.finally(done)
.done();

Also, another way is to use the function done(err) in the .catch() method, instead of using the method .finally(done). Like this:

.catch(function(err){
  test.fail(err.message);
  done(err);
})
.done();

Do not forget the .done() method at the end, otherwise it's an unhandled error.