3

I have an event handler function that takes some event data and a callback function as input.

This event handler is using a promise to do its job:

function myHandler(event, callback) {
  somePromise(event).then((result) => {
    if (result.Error) {
      callback(error);
    } else {
      callback(null, result.SuccessData);
    }
  });
}

I have the following code to test the handler:

it('test handler', function(done) {
  let event = {...};
  myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
    done();
  }
});

When running this test, I receive this error:

(node:3508) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): AssertionError: expected 'unexpected' to equal 'expected'

and a the end of all the tests:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

but yet the test is still passing...

Why is this error occuring while the done() function is called?

Yannick Blondeau
  • 9,465
  • 8
  • 52
  • 74

2 Answers2

2

Wrap your test into a promise that rejects if the assertion fails.

it('test handler', () => {
  let event = {...}
  return new Promise((resolve, reject) => {
    myHandler(event, (error, success) => {
      try {
        expect(success).to.not.be.null;
        expect(error).to.be.null;
        expect(success.member).to.be.equal('expected');
        resolve();
      } catch (err) {
        reject(err);
      }
    });
  });
});
Korbinian Kuhn
  • 726
  • 4
  • 9
1

You're using Promises. You can either return your Promise without using done, like this:

// Note the absence of the done callback here
it('test handler', function() {
  let event = {...};
  return myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
  }
});

Or use Chai As Promised:

it('test handler', function(done) {
  let event = {...};
  myHandler(event, function(error, success) {
    expect(success).to.not.be.null;
    expect(error).to.be.null;
    expect(success.member).to.be.equal('expected');
  }.should.notify(done)
});

The later seems better to me, as if you forget the return in the first example, your tests can silently fail.

SylvainC
  • 104
  • 6
  • 1
    As `myHandler` is not a promise, returning is does not work unfortunately. I may give Chai As Promised a try but will it work if the tested method is not a promise? – Yannick Blondeau Mar 07 '18 at 19:16