jest: jest-worker fails with "Do not know how to serialize a BigInt" in `messageParent.ts` instead of showing the actual assertion error message when there are 2 or more test suite files executing in parallel

Link to repl or repo (highly encouraged)

Minimal reproduction repo: jest-bigint-worker-issue

šŸ› Bug Report

When you have multiple test suite files executing in parallel, and some of the tests are asserting values with bigint numbers in them and the assertion fails, instead of showing this assertion error message, jest-worker fails itself on attempt to serialise this value during the call to the:

parentProcess.send([_types().PARENT_MESSAGE_CUSTOM, message]);

(in messageParent.js)

I assume thatā€™s because message includes failureDetails.matcherResult holding the compared bigint values that canā€™t be passed to process.send(), as unlike worker_threads it does not support non-json values out of the box.

To Reproduce

Steps to reproduce the behavior:

git clone git@github.com:klesun-productions/jest-bigint-worker-issue.git # clone minimal reproduction repo
cd jest-bigint-worker-issue
npm ci # install jest dependency
npm test # run the test that reproduces the issue

Expected behavior

You should have seen the assertion error informing you that expect(1n).toEqual(2n); expectation failed

Actual behavior

But instead you get following output due to an internal jest-worker error:

 PASS  tests/some-other.test.js
  āœ“ should succeed (2 ms)

 FAIL  tests/bigint.test.js
  ā— Test suite failed to run

    TypeError: Do not know how to serialize a BigInt
        at stringify (<anonymous>)

      at messageParent (node_modules/jest-worker/build/workers/messageParent.js:42:19)

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.777 s

With no details of what the actual error that jest-worker tried to report was in tests/bigint.test.js.

envinfo

  System:
    OS: macOS 11.3.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 14.17.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.13 - /usr/local/bin/npm
  npmPackages:
    jest: ^27.0.5 => 27.0.5

Misc

I assume thatā€™s a transport issue that user of jest is not supposed to be aware of. One thing I did that at least somehow solved the absence of the real message was patching the jest-worker wrapping the call to parentProcess.send() in a try-catch and console.log-ing the message whose serialisation failed:

try {
  parentProcess.send([_types().PARENT_MESSAGE_CUSTOM, message]);
} catch (error) {
  console.error('jest-worker message serialisation failed', error);
  console.dir(message, {depth: 10});
  throw error;
}

There is likely a number of ways how to better address this problemā€¦

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 38
  • Comments: 26 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Any update?

For those of you that got here because a failing test involves some BigInt, you can temporarily circumvent this issue by setting maxWorkers: 1 in your jest configuration.

The workerthreads configuration option might help. It is a new feature which was shipped yesterday with Jest v29.5.

Note that this is !!! strictly experimental !!! and wasnā€™t tryout widely at all. Use it at your own risk.

Currently I run tests with workerThreads: true in one repo. Give it a try.

This is quite unplesant issue. Testing library cannot handle one of built-in language types? Srsly? Please fix it somebody!

@JCastrejonE serialization (currently using JSON, it does not support BigInt) only happens when sending data between worker threads. Limiting workers to 1 eliminates the need to serialize at all. Until a fix for this, we wait for our single worker to finish.

If only a small number of tests involve BigInt you could separate them, such as (!!! not tested !!!)

{
  "scripts": {
    "test:no-bigint": "jest --testPathIgnorePatterns=.*\\.bigint\\.test\\.js",
    "test:bigint": "jest --maxWorkers=1 --testPathPattern=.*\\.bigint\\.test\\.js",
    "test": "npm run test:no-bigint && npm run test:bigint"
  }
}

For others running into the same issue, weā€™re trying a fix that doesnā€™t rely on the experimental workerThreads. Weā€™re patching jest to use nodejs inter-process advanced serialization instead of JSON. This seems to handle BigInts (and other data types) ok, and havenā€™t yet found any issues with it.

This requires patching the forkOptions used in jest-runner, itā€™s a one-liner. Curious if itā€™d make sense for jest itself to adopt the change. Happy to send a PR, but itā€™s unclear to me if thisā€™d be breaking other things.

Anu updates on solving this issues on jest without workarounds?

Realized Prisma is returning BigInt which made my zod parsing fail on a raw query while validating the return data, which lead me to here. Luckily our system is running the latest Node which will support structured cloning and weā€™re up to date to be on a version of Jest that supports the experimental workerThreads, but I would prefer to get away from them, as it seems I do not get a performance boost from the flag, if anything a slow down. I guess another route would have been to just make the type validation on Zod to be looser to accept int or BigInt, but Iā€™d rather be more explicit hereā€¦

Will look into this tomorrow!