2

I made a very simple RESTful API that allows users to add, delete and update information about Hogwarts students. Mongo acts as the persistence layer.

A GET request to url/students is supposed to return a list of all student objects. While writing the test for it I wrote

expect(res).to.equal('student list');

This is just for an initial check to make sure the test would fail but it isn't instead I get this error:

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: expected { Object (domain, _events, ...) } to equal 'student list'

So it knows that the two values are different but instead of the test failing it's throwing an error. I've pasted the full test code below.

let chai = require('chai');
let chaiHttp = require('chai-http');
var MongoClient = require('mongodb').MongoClient;
chai.use(chaiHttp);
const expect = chai.expect;

describe('Students', async () => {
  describe('/GET students', () => {
    it('should GET all the students', async () => {
      chai.request('http://localhost:5000')
        .get('/students')
        .then(function (res) {
          try {
            expect(res).to.equal('hola');
          } catch (err) {
            throw err;
          }
        })
        .catch(err => {
          throw err; //this gets thrown
        })
    });
  });
});

And if you can show me the syntax of properly using async await for writing these tests please do that too.

5
  • .catch() after then(...). Note: async statement make sense only if you use the await statement Commented Apr 5, 2019 at 18:33
  • That doesn't work, I'll update the code above though. After I added the .catch, it caught the AssertionError but the point is why is there an AssertionError at all? Commented Apr 5, 2019 at 18:41
  • console.log res, if res != "hola", AssertionError is thrown Commented Apr 5, 2019 at 18:46
  • res is supposed to be an object, but the expect should fail the test, why should there be an error? Why is the test not failing ? Commented Apr 5, 2019 at 18:58
  • try a sample it('should be true', ()=>expect(false).to.equal(true)) , if it works like you want and not your example, that's because of the promise. Maybe you can check this: stackoverflow.com/questions/55520801/… Commented Apr 5, 2019 at 19:06

1 Answer 1

2

The test passes and logs the "Unhandled promise rejection" warning because the error is thrown within a Promise which just causes the Promise to reject.

Since the Promise is not returned or await-ed, the test completes successfully...

...and because nothing is waiting for or handling the rejected Promise, Node.js logs a warning.

Details

An error thrown in a test will fail the test:

it('will fail', function () {
  throw new Error('the error');
});

...but a rejected Promise will not fail the test if it is not returned or await-ed:

it('will pass with "Unhandled promise rejection."', function() {
  Promise.reject(new Error('the error'));
});

.catch returns a Promise so throwing in a .catch returns a rejected Promise, but if that Promise is not returned or await-ed then the test will also pass:

it('will also pass with "Unhandled promise rejection."', function() {
  Promise.reject(new Error('the error')).catch(err => { throw err });
});

...but if a rejected Promise is returned or await-ed then the test will fail:

it('will fail', async function() {
  await Promise.reject(new Error('the error'));
});

And if you can show me the syntax of properly using async await for writing these tests please do that too.

For your test you can simplify it to this:

const chai = require('chai');
const expect = chai.expect;
const chaiHttp = require('chai-http');
chai.use(chaiHttp);

describe('Students', async function() {
  describe('/GET students', function() {
    it('should GET all the students', async function() {
      const res = await chai.request('http://localhost:5000').get('/students');
      expect(res).to.equal('hola');  // <= this will fail as expected
    });
  });
});

Details

From the chai-http doc:

If Promise is available, request() becomes a Promise capable library

...so chai.request(...).get(...) returns a Promise.

You can simply await the Promise and the test will wait until the Promise resolves before continuing.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! This was extremely helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.