jest: Cannot load native module when running under jest
š Bug Report
I can load a native module in a regular script just fine, but I cannot do the same in a spec being executed by jest.
To Reproduce
Steps to reproduce the behavior:
Install native module like this:
$ npm config set @sap:registry https://npm.sap.com
$ npm install @sap/hana-client
Reproducible example:
$ cat package.json
{
"name": "foo",
"version": "1.0.0",
"description": "",
"main": "foobar.spec.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@sap/hana-client": "^2.3.123",
"jest": "^23.6.0"
}
}
$ cat foobar.spec.js
require("@sap/hana-client");
$ node -v
v8.12.0
$ DEBUG=*
$ node foobar.spec.js
@sap/hana-client:index Starting index.js +0ms
@sap/hana-client:index Attempting to load Hana node-hdbcapi driver +3ms
@sap/hana-client:index ... Trying user-built copy... +0ms
@sap/hana-client:index ... Looking for user-built copy in /Users/else/code/foo/node_modules/@sap/hana-client/build/Release/hana-client.node ... +0ms
@sap/hana-client:index Not found. +0ms
@sap/hana-client:index ... Trying prebuilt copy... +0ms
@sap/hana-client:index ... Looking for prebuilt copy in /Users/else/code/foo/node_modules/@sap/hana-client/prebuilt/darwinintel64-xcode7/hana-client_v8.node ... +0ms
@sap/hana-client:index Loaded. +50ms
@sap/hana-client:index Success. +0ms
$ echo $?
0
$ node_modules/.bin/jest --runInBand
@sap/hana-client:index Starting index.js +0ms
@sap/hana-client:index Attempting to load Hana node-hdbcapi driver +1ms
@sap/hana-client:index ... Trying user-built copy... +0ms
@sap/hana-client:index ... Looking for user-built copy in /Users/else/code/foo/node_modules/@sap/hana-client/build/Release/hana-client.node ... +0ms
@sap/hana-client:index Not found. +0ms
@sap/hana-client:index ... Trying prebuilt copy... +0ms
@sap/hana-client:index ... Looking for prebuilt copy in /Users/else/code/foo/node_modules/@sap/hana-client/prebuilt/darwinintel64-xcode7/hana-client_v8.node ... +0ms
@sap/hana-client:index Failed to load DBCAPI. +2ms
@sap/hana-client:index Could not load: Prebuilt copy did not satisfy requirements. +0ms
@sap/hana-client:index Could not load modules for Platform: 'darwin', Process Arch: 'x64', and Version: 'v8.12.0' +0ms
FAIL ./foobar.spec.js
ā Test suite failed to run
Failed to load DBCAPI.
at /Users/else/code/foo/node_modules/jest-runtime/build/index.js.requireModule (../node_modules/jest-runtime/build/index.js:372:31)
at /Users/else/code/foo/node_modules/@sap/hana-client/lib/index.js.Object.<anonymous> (node_modules/@sap/hana-client/lib/index.js:127:14)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.022s
Ran all test suites.
Expected behavior
No error related to module loading
Link to repl or repo (highly encouraged)
https://transfer.sh/(/JOeLK/example.tar.gz).tar.gz
Run npx envinfo --preset jest
Paste the results here:
$ npx envinfo --preset jest
npx: installed 1 in 3.457s
System:
OS: macOS 10.14
CPU: (4) x64 Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
Binaries:
Node: 8.12.0 - ~/.nvm/versions/node/v8.12.0/bin/node
Yarn: 1.10.1 - ~/.nvm/versions/node/v8.12.0/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.12.0/bin/npm
npmPackages:
jest: ^23.6.0 => 23.6.0
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 23 (6 by maintainers)
We were having the same issues combining the SAP Hana client library with Jest.
Setting environment variables was no solution for us, since we are working on different systems (Windows, Linux, Mac). The following steps solved it for us:
Please note that this was tested with version 2.4.126 of @sap/hana-client and things might change with newer versions.
Thanks for sharing, IMO itās much easier though to just
require("@sap/hana-client/build.js");
in your jest config.The problem here is with
process.env
.Every test file is run inside VM module. But VM context does not have Node globals(require, process and etc), so Jest modifies these globals and then injects them in. VM and these modifications are needed to ensure all test files run in isolation.
a.test.js
should not affect the outcome ofb.test.js
.process.env
is one of the globals which is modified. Jest makes a new object from the prototype ofprocess.env
and reimplements the behaviour. Problem is thatprocess.env
is a bit special since Node stores env variables in C++ core and passes it down to child processes and native bindings if needed.So if you do this in normal Node process
All the child processes and native bindings can see this value in their Environment Variables. This is how
hana-client
works. It read this value from Environment Variables and then tries to load the file.The reason it does not work with Jest is because Jestās
process.env
is just a Javascript object. When you set a value on it, this update only exists in Javascriptās context. Child processes and Native bindings cannot see it. Sincehana-client
cannot see this value it fails. But if you do it outside of test context, like in global setup it should work.I donāt think this issue is solvable from Jestās codebase, you will have to use the workarounds described above. Nodejs only has one environment per process. if you run your code in VM module, you get a new Javascript Context but you cannot create new environment without creating a new process.
It seems the issue still exists. It fails even when hard coding the
DBCAPI_API_DLL
and loading the hana-client like below.seems that the native module loading done thru jest, behaves different than not via jest.
The stack trace is as below:
Is there anything under the scenes that would explain why the native (nodejs) require for native modules would behave different via jest? Or there are more variables required to be set for loading that hana-client module.
Oh my bad.
https://github.com/facebook/jest/blob/master/packages/jest-util/src/createProcessObject.js#L19 I changed a return statement of this function with
return process.env