ava

Can I somehow declare that a test expects to have unhandled rejections?


I have a library that imposes "metering" on some code. The normal case is easy to test where the code runs to completion and the meter is not exceeded.

I also want to test the case where the meter is exceeded, causing the code under test to throw forever until it unwinds to the caller. It is easy to test that the code only executes the parts I expect. However, in the case of promises, the exceeded meter causes some unhandled rejections in the code under test, as expected.

AVA currently fails my test run with:

  1 test passed
  1 unhandled rejection

Effectively, the test reduces to:

const expectedLog = ['a'];
test('unhandled rejection', async t => {
  const log = [];
  // I don't have control over the code in f():
  const f = async () => {
    log.push('a');
    // This is a side-effect, but fails the test.
    Promise.reject(RangeError('metering'));
    throw RangeError('metering');
  };
  await t.throwsAsync(() => f(), { instanceOf: RangeError });
  t.deepEqual(log, expectedLog);
});

Is there any way for me to tell AVA that I expected the 1 unhandled rejection?

I require not to modify the code under test (the f function above), as the whole point is to test that metering stops the code dead in its tracks no matter what that untrusted code is.


Solution

  • Is there any way for me to tell AVA that I expected the 1 unhandled rejection?

    No. Unhandled rejections are indicative of bugs and therefore AVA will fail the test run. As AVA's maintainer I don't think there's enough reason to change that behavior.

    I require not to modify the code under test (the f function above), as the whole point is to test that metering stops the code dead in its tracks no matter what that untrusted code is.

    Rejecting a promise, that is then garbage collected, won't impact the untrusted code. If you're in an async function you can use throw directly.