Bev01
Bev01

Reputation: 11

Mocha Test - can't pass test for rejected promise using async/await

Using mocha and chai, I'm trying to pass my second test to get the rejected promise, but instead I get this error Error: the string "error" was thrown, throw an Error.

function fn(arg) {
  return new Promise((resolve, reject) => {
    if (arg) {
      resolve('success')
    } else {
      reject('error')
    }
  })
}

describe('Interpreting status', function() {
  it('should return the promise without error', async function(){
    const arg = true
    expect(await fn(arg)).to.equal('success')
  });

  it('should return the promise with an error', async function(){
    const arg = false
    expect(await fn(arg)).to.be.rejectedWith('error')
  });
});

Upvotes: 0

Views: 553

Answers (1)

Ramaraja
Ramaraja

Reputation: 2626

This works perfectly for me,

const chai = require('chai');
const expect = chai.expect;
chai.use(require('chai-as-promised'));

function fn(arg) {
  return new Promise((resolve, reject) => {
    if (arg) {
      resolve('success');
    } else {
      reject(new Error('error'));
    }
  });
}

describe('Interpreting status', function () {
  it('should return the promise without error', async function () {
    const arg = true;
    expect(await fn(arg)).to.equal('success');
  });

  it('should return the promise with an error', async function () {
    const arg = false;
    await expect(fn(arg)).to.be.rejectedWith(Error);
  });
});

The problem with your 2nd test is that when you do await fn(arg) you get an error being thrown instead of the rejected promise that you are expecting.
Hence, you see the message Error: the string "error" was thrown, throw an Error :)
Remember that if you await on a promise that rejects an error will be thrown that must be handled with a try...catch.
So, if you want to test with rejectedWith then don't use async/await.

Also, whenever you do a Promise rejection, you should reject with an error, not with a string. I have changed the rejection value to new Error('error') and I am asserting for the error type in rejectedWith

If you strictly want to go by your usecase, this should work for the 2nd test,

  it('should return the promise with an error', async function () {
    const arg = false;
    try {
      await fn(arg);
      expect.fail();
    } catch (error) {
      expect(error).to.equal('error');
    }
  });

Upvotes: 2

Related Questions