Jest: Jest gives no indication that test fails because of unhandled promise rejection.

Created on 20 Nov 2019  ·  8Comments  ·  Source: facebook/jest

🐛 Bug Report

When Jest fails a test for what it thinks - wrongly - is an unhandled rejection, it does not indicate this at all.

To Reproduce

This code in a test module causes Jest to wrongly think a promise rejection isn't going to be handled.

describe("whatever", () => {
  it("fails for no reason", async () => {
    const p = Promise.reject(new Error("Shouldn't fail the test"));
    await new Promise(r => setTimeout(r, 100));
    await expect(p).rejects.toMatchObject({
      message: "Shouldn't fail the test",
    });
  });
});

Output:

 FAIL  src/test/plugging-in.test.ts
  DeviceManager - plugging and unplugging
    ○ skipped becomes useful after being plugged in
  whatever
    × fails for no reason (12ms)

  ● whatever › fails for no reason

    an error message

      90 | describe("whatever", () => {
      91 |   it("fails for no reason", async () => {
    > 92 |     const p = Promise.reject(new Error("an error message"));
         |                              ^
      93 |     await new Promise(r => setTimeout(r, 100));
      94 |     await expect(p).rejects.toMatchObject({
      95 |       message: "an error message",

      at Object.it (src/test/plugging-in.test.ts:92:30)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 skipped, 2 total
Snapshots:   0 total
Time:        4.355s, estimated 6s
Ran all test suites matching /plugging-in/i with tests matching "whatever".

Note that nothing in the output conveys the real reason this test failed.

Expected behavior

Something in the output says that Jest failed the test because it can't guarantee that the promise rejection will be handled. For instance, instead of:


     an error message

something like:

    Unhandled Promise Rejection:
    an error message
Bug Report Needs Repro Needs Triage

Most helpful comment

I would also like to add that the problem here is not only "no indication", but also the fact that the test fails: I was writing a test for utility function and I need to test that this function handles both successful and failing callbacks passed to it.
Seems like the "negative" test fails for me anyway, even with expect(promise).rejects...., try/catch.

P.S.
Also if I add const promise = Promise.reject('aaaa') to the top level in the file (outside describe) Jest will randomly fail first two tests. Very weird...

All 8 comments

A workaround for others encountering this problem, or rather, a work around for the difficulty of Jest not liking unhandled rejections:

```
/**

  • A function to wrap the Promise constructor such that no rejections are considered unhandled
  • by either Node or Jest. Whatever handlers can still be attached and rejections turned into
  • thrown exceptions where ever the returned promise is awaited.
    */
    function makePromise(callback) {
    const promise = new Promise(callback);
    promise.catch(()=>{});
    return promise;
    }

Oh wow ok I've just spent far too long trying to figure out how Jest was even seeing the error it was reporting. Really could do with jest saying something, anything, about how it caught the error. Unhandled error/rejection bugs can be subtle and hard to track down, and often appear when you end up with the worst case async scenario where code is unintentionally executing in the background that can't be sequenced and errors can't be handled. Having just show the error without indicating how it found the error was very confusing, especially since it seems to override/ignore any unhandled rejection/exception handlers you add in test.

@JoeLangewayClear's workaround will suppress these errors, but it's kind of like disabling the _engine fault_ light in your car and claiming you "fixed it"

image

I would also like to add that the problem here is not only "no indication", but also the fact that the test fails: I was writing a test for utility function and I need to test that this function handles both successful and failing callbacks passed to it.
Seems like the "negative" test fails for me anyway, even with expect(promise).rejects...., try/catch.

P.S.
Also if I add const promise = Promise.reject('aaaa') to the top level in the file (outside describe) Jest will randomly fail first two tests. Very weird...

I would also like to add that the problem here is not only "no indication", but also the fact that the test fails

This is intended, the test should fail on unhandled rejection. Short reasoning here. But nevertheless I agree a hint in the error would be great.

That sounds reasonable, but is "unhandled rejection" checked at the end of the test or immediately?
My use case was to have several promises in variables and only do something with them at the end of the test (wait for all and verify some are rejected).

Immediately, I believe this is using Node's native handling mechanism for rejected Promises. However note that this does not mean the test case will be aborted, it will be marked as failed but there is no way to stop the test case function execution early.

This issue seems related to https://github.com/facebook/jest/issues/5958

Was this page helpful?
0 / 5 - 0 ratings