Adam Stelle Adam Stelle - 1 month ago 17
Node.js Question

Mocha Chai timeout error on 'expect' statement failure

I'm getting unexpected timeout behavior using Mocha and Chai's 'expect' statement when a test fails.

The code:

require('./lib/test-env.js');

const expect = require('chai').expect;
const estimateQuery = require('../lib/estimate-query-helper.js');

describe('testing auth routes', function() {
describe('testing estimate query helper', function() {
it('should return an average daily rate and occupancy rate', (done) => {
estimateQuery.getEstimate()
.then(result => {
expect(result[0]['avg(`Average Daily Rate`)']).to.be.a('number');
expect(result[0]['avg(`Occupancy Rate LTM`)']).to.be.a('number');
done();
});
});
});
});


When I run this with correct expect values, test passes w/no timeout (and I've checked to see the returned values are all correct). But when I change 'number' to (for example) 'string' on either of the statements, rather than failing and throwing 'Expected ..., Actual ..." error, it times out. I've checked out the docs and Chai's open issues and can't find an answer.

Thanks very much in advance for your help.

Answer

That's because the promise is catching the error that's thrown by the failing expectation, resulting in the done callback not being called.

Mocha understands promises, so you can return a promise instead of using a callback:

describe('testing auth routes', function() {
  describe('testing estimate query helper', function() {
    it('should return an average daily rate and occupancy rate', () => {
      return estimateQuery.getEstimate()
        .then(result => {
          expect(result[0]['avg(`Average Daily Rate`)']).to.be.a('number');
          expect(result[0]['avg(`Occupancy Rate LTM`)']).to.be.a('number');
        });
    });
  });
});

Any failed expectations will then result in the promise being rejected and the test being reported as failing.

Alternatively, you could stick with the done callback and add a catch:

describe('testing auth routes', function() {
  describe('testing estimate query helper', function() {
    it('should return an average daily rate and occupancy rate', (done) => {
      estimateQuery.getEstimate()
        .then(result => {
          expect(result[0]['avg(`Average Daily Rate`)']).to.be.a('number');
          expect(result[0]['avg(`Occupancy Rate LTM`)']).to.be.a('number');
          done();
        })
        .catch(done);
    });
  });
});