Yashua Yashua - 6 months ago 71
Javascript Question

Testing rejected promise in Mocha/Chai

I have a class that rejects a promise:

Sync.prototype.doCall = function(verb, method, data) {
var self = this;

self.client = P.promisifyAll(new Client());

var res = this.queue.then(function() {
return self.client.callAsync(verb, method, data)
.then(function(res) {
return;
})
.catch(function(err) {
// This is what gets called in my test
return P.reject('Boo');
});
});

this.queue = res.delay(this.options.throttle * 1000);
return res;
};

Sync.prototype.sendNote = function(data) {
var self = this;
return self.doCall('POST', '/Invoice', {
Invoice: data
}).then(function(res) {
return data;
});
};


In my test:

return expect(s.sendNote(data)).to.eventually.be.rejectedWith('Boo');


However while the test passes it throws the error to the console.

Unhandled rejection Error: Boo
...

With non promise errors I have used bind to test to prevent the error from being thrown until Chai could wrap and test:

return expect(s.sendNote.bind(s, data)).to.eventually.be.rejectedWith('Boo');


However this does not work with this and returns:

TypeError:
[Function] is not a thenable.


What is the correct way to test for this?

Answer

You're getting the error because sendNote is being rejected and you're not catching it.

Try:

var callPromise = self.doCall('POST', '/Invoice', {
  Invoice: data
}).then(function(res) {
  return data;
});

callPromise.catch(function(reason) {
  console.info('sendNote failed with reason:', reason);
});

return callPromise;

Looks like you'll also have to move your existing catch one block out:

var res = this.queue.then(function() {
  return self.client.callAsync(verb, method, data)
    .then(function(res) {
      return;
    });
  }).catch(function(err) {    
    // This is what gets called in my test    
    return P.reject('Boo');
  });