question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Test cannot change process environment

See original GitHub issue

🐛 Bug Report

It is not possible for a test to set the process environment as node_modules/jest-util/build/installCommonGlobals.js runs node_modules/jest-util/build/createProcessObject.js createProcessEnv() which replaces the real process.env with a fake one. This means that tests cannot communicate with binary/native modules via the environment.

My specific use case is, in a nodejs jest test, a need to set KRB5_CONFIG in the real process environment prior to interacting with the native library MIT krb5 via https://www.npmjs.com/package/gssapi.js.

To Reproduce

Rather than my use case, which requires a third-party binary node module, I will just provide a repro case that uses standard node modules. This example require a system with a bash shell, where it will write output: bar to standard output.

const child = require("child_process");

process.env.foo = "bar";
child.exec("echo -n $foo", (err, stdout, stderr) => {
    console.log(`output: ${stdout}`);
});

If this code is instead moved into a jest test it will just write output: to standard output as the foo variable will only have been set in the jest fake process.env, not in the real (OS level) process environment, so it is not inherited by the process that we start.

In this repro case you can of course just pass the env explicitly as an option to child_process.exec(), but that is besides the point. The point is that process.env changes do not update the real system/OS-level process environment, which prevents communication via the process environment to binary modules.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
SimenBcommented, Feb 27, 2022

The problem is Date only reading the default from env (AFAIK). Unfortunately, I think that’ll only be fixed by Temporal: https://tc39.es/proposal-temporal/docs/#Temporal-TimeZone.

If you’re stuck with legacy Date, what you could do is write a custom test environment that sent the real process.env through. You’d then opt out of the test isolation, but that might be a tradeoff that’s worth it to you.

Another option is to create a test env that allows you to set timezone through config. Jest 28 (currently in alpha) allows you to set config per test file via docblock.

// timeZoneEnvironment.js
const {TestEnvironment} = require('jest-environment-node');

module.exports = class TimeZoneEnv extends TestEnvironment {
  constructor(config, context) {
    super(config, context);

    const timeZoneFromOptions =
      config.projectConfig.testEnvironmentOptions.timezone;

    if (timeZoneFromOptions) {
      process.env.TZ = timeZoneFromOptions;
    }
  }
};
// cairo.test.js
/**
 * @jest-environment ./timeZoneEnvironment.js
 * @jest-environment-options {"timezone": "Africa/Cairo"}
 */

test('dummy', () => {
  console.log(new Date().toString());
});
// new-york.test.js
/**
 * @jest-environment ./timeZoneEnvironment.js
 * @jest-environment-options {"timezone": "America/New_York"}
 */

test('dummy', () => {
  console.log(new Date().toString());
});

Running that prints

 $ yarn jest cairo new-york
 PASS  ./cairo.test.js
  ● Console

    console.log
      Sun Feb 27 2022 21:57:40 GMT+0200 (Eastern European Standard Time)

      at Object.log (cairo.test.js:7:11)

 PASS  ./new-york.test.js
  ● Console

    console.log
      Sun Feb 27 2022 14:57:40 GMT-0500 (Eastern Standard Time)

      at Object.log (new-york.test.js:7:11)


Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.571 s, estimated 1 s
Ran all test suites matching /cairo|york/i.

Note that these tests should then run sequentially since they both mutate the same global process environment

0reactions
github-actions[bot]commented, Mar 30, 2022

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Change process.env variable for single test using JEST
my question is, how do i change process.env.LOCAL_ENVIRONMENT to test (or anything else) in foo.test.js ? Just need to do this in a...
Read more >
change environment of a running process - Unix & Linux Stack ...
Just run a job with path to a temporary unique directory and pass the same path to the child shell script. Script will...
Read more >
Test Environment Management Best Practices - Plutora.com
Why Is the Test Environment Management Process Important? ... Further, it isn't change-controlled and cannot be audited.
Read more >
Environment Extensions are set but process can't read them
Solution: Running a document again in Test Mode does not copy the environment extensions. Therefore, those values will not be present when Test...
Read more >
Create target environment - Azure Pipelines - Microsoft Learn
Go to Organization Settings > Users and check if you have the stakeholder role. The stakeholder role can't create environments. Change your ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found