0

I have the following promises. I know they are working correctly, as the console.log output in funcThree returns the correct data. How do I prove this through testing?

Basically, how do I test this promise? I have tried to tests below, but no matter what I put in there (including expect(false).to.be.true), it always returns true. I do not believe it is actually reaching the expect statements.

CODE

let number = 0;
let count = 0;

// Find Mongoose document
function funcOne(query) {
  return new Promise(function (resolve, reject) {
    MongooseDocument.find(query)
      .exec(function (err, results) {
        if (err) {
          reject(err);
        }
        resolve(results);
      });
  });
}

// Iterate over each document and adjust external value
function funcTwo(documents) {
  return new Promise(function (resolve, reject) {
    _.each(documents, function (document) {
      count += 1;
      number += document.otherNumber;
    });
    if (count >= documents.length) {
      resolve({
        count,
        number,
      });
    }
  });
}

// Chain promises and return result
function funcThree(query) {
  return funcOne(query).then(funcTwo).then(function (result) {
    console.log("==================");
    console.log(result);
    return result;
  });
}

TEST EXAMPLE

// The expect test below never runs! How do I test this promise? Or
// better yet, how do I get the value returned as a result from the
// promise to test that?
it('should return an object', function () {
  funcThree(query).then(function(result) {
    return expect(result).to.be.an('object');
  });
});
Tori Huang
  • 527
  • 1
  • 7
  • 25

1 Answers1

1

When using chai and chai-as-promised you need to instruct chai to actually use chai-as-promised.

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

Also to convert the assertion to return a promise you need to use the keyword eventually and you need to return the promise back to it(). When using chai-as-promised you need to perform the assertion against the actual promise returning function, in this case, funcThree(query). This is why you're always having your test function return true, you're not actually waiting for the Promise to resolve and since no error sent back to your it() then it is assumed succesful. So your test example above should be as follows:

it('should return an object', function () {
  return expect(funcThree(query)).to.eventually.be.a('object');
});

You can also make multiple assertions against the same promise using the following syntax

it('should return an object', function () {
  var funcThreePromise = funcThree(query);

  // Promise below is whatever A+ Promise library you're using (i.e. bluebird)
  return Promise.all([
    expect(funcThreePromise).to.eventually.be.fulfilled,
    expect(funcThreePromise).to.eventually.be.a('object')
  ]);
});
peteb
  • 18,552
  • 9
  • 50
  • 62