callum
callum

Reputation: 37709

How to 'reverse' the rejection/fulfillment of a promise?

For a mocha test, I want to assert that a promise will eventually reject.

I don't want to use chai-as-promised. I'd prefer to just use Node's standard assert module, and to just use standard ES6 promises.

The best I've come up with is this, but it feels slightly hacky:

it('foo should reject given bad data', function () {
  var rejected;

  return foo('bad data').catch(function (err) {
    rejected = true;
  }).then(function () {
    assert(rejected);
  });
});

Can anyone suggest a neater, more expressive way to 'reverse' a promise, so rejection becomes fulfillment and vice versa?

Upvotes: 1

Views: 1670

Answers (3)

You may add a reverse method to Promise prototype and then just use it.

Promise.prototype.reverse = function() {
  return new Promise((resolve, reject) => {
    this.then(reject).catch(resolve);
  });
}

foo('bad data')
  .reverse()
  .then(e => assert(true))
  .catch(e => assert(false));

Upvotes: -1

roosyrex
roosyrex

Reputation: 61

You could do it using a single .done() like so:

it('foo should reject given bad data', function () {
  return foo('bad data')
  .done(assert.equal.bind(null, 'false', 'true', null), assert);
});

I've used values for assert.equal that will provide the equivalent of assert(false), but you can obviously remove the last null if you want to print the actual result.

Edit: You could actually make this cleaner for multiple tests by defining your own assertFail function:

function assertFail () { assert(false); }

it('foo should reject given bad data', function () {
  return foo('bad data')
  .done(assertFail, assert);
});

Upvotes: 1

zzzzBov
zzzzBov

Reputation: 179046

You could just assert on both the resolution and rejection callbacks passing true or false directly.

it('foo should reject given bad data', function () {
  return foo('bad data').then(function () {
      assert(false);
  }, function () {
      assert(true);
  });
});

Upvotes: 1

Related Questions