jest
jest copied to clipboard
[Bug]: Failure to expect rejection of Bluebird promises
Version
27.4.7
Steps to reproduce
Run this test:
import { each } from 'bluebird';
test('my test', async () => {
await expect(each([Promise.reject('foo')], () => {})).rejects.toEqual('foo');
});
Expected behavior
Test should pass.
Actual behavior
Test fails with error:
Error: thrown: "foo"
at _getError (/myproject/node_modules/jest-circus/build/utils.js:566:18)
at Array.map (<anonymous>)
at makeSingleTestResult (/myproject/node_modules/jest-circus/build/utils.js:507:38)
at /myproject/node_modules/jest-circus/build/testCaseReportHandler.js:19:58
at dispatch (/myproject/node_modules/jest-circus/build/state.js:75:11)
at _runTest (/myproject/node_modules/jest-circus/build/run.js:167:3)
at _runTestsForDescribeBlock (/myproject/node_modules/jest-circus/build/run.js:66:9)
at _runTestsForDescribeBlock (/myproject/node_modules/jest-circus/build/run.js:60:9)
at run (/myproject/node_modules/jest-circus/build/run.js:25:3)
at runAndTransformResultsToJestFormat (/myproject/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:170:21)
at jestAdapter (/myproject/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:82:19)
at runTestInternal (/myproject/node_modules/jest-runner/build/runTest.js:389:16)
at runTest (/myproject/node_modules/jest-runner/build/runTest.js:475:34)
at TestRunner.runTests (/myproject/node_modules/jest-runner/build/index.js:111:12)
at TestScheduler.scheduleTests (/myproject/node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (/myproject/node_modules/@jest/core/build/runJest.js:404:19)
Additional context
This issue (or similar) seemed to have been posted here in the past in #8667, but was never addressed.
jest.config.js
:
// All tests
// fix resolution of config/*.json in tests run from IntelliJ
process.env.NODE_CONFIG_DIR = `${__dirname}/config`;
/** @type {import("ts-jest/dist/types").InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
rootDir: __dirname,
testMatch: [
"<rootDir>/test/**/*.test.ts"
],
modulePathIgnorePatterns: ["<rootDir>/out/"],
moduleNameMapper: {
"^src/(.*)$": "<rootDir>/src/$1",
"^test/(.*)$": "<rootDir>/test/$1"
},
globals: {
"ts-jest": {
tsconfig: "<rootDir>/test/tsconfig.json"
}
},
resetMocks: true,
};
Environment
System:
OS: macOS 12.6
CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Binaries:
Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
npm: 8.12.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
npmPackages:
jest: ^27.4.7 => 27.4.7
bluebird: 3.7.2
Hey there! I tried your test using Jest 27.5.1 (creating a create-react-app environment to do it), and it passed. Maybe upgrading jest version would fix it?

@feliperli I updated to the latest Jest (29.3.1
) and I get the same error.
I'm not sure about the test setup of create-react-app as I'm not using React.
Yeah, I created a simple jest environment and create-react-app indeed does something more with jest (a config or a plugin maybe).
it is weird because in a scenario like
import { each } from "bluebird";
test("my test", async () => {
await expect(each([Promise.reject("foo")], () => {})).rejects.toEqual("foo");
});
test("my test resolved", async () => {
await expect(each([Promise.resolve("foo")], () => {})).resolves.toEqual([
"foo",
]);
});
The first test fails, but the second passes. And if I try to change to
import { each } from "bluebird";
test("my test", async () => {
await expect(each([Promise.reject("foo")], () => {})).rejects.toEqual("foo2");
});
});
I get
Expected: "foo2"
Received: "foo"
So, the test when ran is indeed receiving "foo", but failing.
Hey @eyalroth to fix your problem you should
import Promise, { each } from 'bluebird'
this will ensure promise compatibility with bluebird and jest. If this solve your problem, please don't forget to close the issue :)
@feliperli Sorry for the late reply.
The snippet you added makes the test fail (as expected) because it makes the line Promise.reject
return a Bluebird (rejected) promise instead of a native one.
However, bluebird is compatible with native promises, and the test should reflect that.
Perhaps in my code I'm using Bluebird's functions for their utility, but I might be dealing with native promises that are emitted by third party libraries. I still want to test my code and see whether it deals with both native and bluebird's promises alike.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
Not stale.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days.
This is an issue with bluebird. Run the following snippet in Node and see await
doesn't work.
// file.mjs
import bluebird from 'bluebird';
try {
await bluebird.each([Promise.reject('booo')], () => {});
} catch {
console.log('caught the error');
}
$ node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "booo".] {
code: 'ERR_UNHANDLED_REJECTION'
}
Node.js v18.14.0
@SimenB I don't see why Jest fails because of this.
The promise returned from bluebird.each
is still a rejected promise:
const p = await each([Promise.reject('booo')], () => {}).catch(e => e);
console.log(p) // prints 'booo'
// also
try {
await each([Promise.reject('booo')], () => {});
} catch (e) {
console.log('caught the error');
console.log(e); // prints 'booo'
}
And if we add global hook on rejections per bluebird's documentation:
process.on("unhandledRejection", function(reason, promise) {});
process.on("rejectionHandled", function(promise) {});
NodeJS doesn't emit PromiseRejectionHandledWarning
anymore, but Jest still fails.
It's also worth noting that Mocha + Chai + chai-as-promised handles this case correctly:
// this passes
await chai.expect(bluebird.each([Promise.reject('booo')], () => {})).to.be.rejected;
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.