J'ai une application qui dépend de variables environnementales comme:

const APP_PORT = process.env.APP_PORT || 8080;

Et je voudrais tester cela par exemple:

  • APP_PORT peut être défini par la variable d'environnement du nœud.
  • ou qu'une application express est en cours d'exécution sur le port défini avec process.env.APP_PORT

Comment puis-je y parvenir avec Jest? Puis-je définir ces process.env variables avant chaque test ou devrais-je m'en moquer d'une manière ou d'une autre?

78
Tomasz Mularczyk 30 déc. 2017 à 15:14

8 réponses

Meilleure réponse

La façon dont je l'ai fait peut être trouvée dans cette question SO.

Il est important de resetModules avant chaque test, puis d'importer dynamiquement le module à l'intérieur le test:

describe('environmental variables', () => {
  const OLD_ENV = process.env;

  beforeEach(() => {
    jest.resetModules() // this is important - it clears the cache
    process.env = { ...OLD_ENV };
    delete process.env.NODE_ENV;
  });

  afterEach(() => {
    process.env = OLD_ENV;
  });

  test('will receive process.env variables', () => {
    // set the variables
    process.env.NODE_ENV = 'dev';
    process.env.PROXY_PREFIX = '/new-prefix/';
    process.env.API_URL = 'https://new-api.com/';
    process.env.APP_PORT = '7080';
    process.env.USE_PROXY = 'false';

    const testedModule = require('../../config/env').default

    // ... actual testing
  });
});
97
Tomasz Mularczyk 10 mai 2019 à 12:53

Une autre option consiste à l'ajouter au fichier jest.config.js après la définition module.exports:

process.env = Object.assign(process.env, {
  VAR_NAME: 'varValue',
  VAR_NAME_2: 'varValue2'
});

De cette façon, il n'est pas nécessaire de définir les variables ENV dans chaque fichier .spec et elles peuvent être ajustées globalement.

3
jahller 4 oct. 2019 à 14:54

Je pense que vous pouvez aussi essayer ceci:

const currentEnv = process.env;
process.env = { ENV_NODE: 'whatever' };

// test code...

process.env = currentEnv;

Cela fonctionne pour moi et vous n'avez pas besoin de modules

0
andy 10 mai 2019 à 09:27

Dans ./package.json:

"jest": {
  "setupFiles": [
    "<rootDir>/jest/setEnvVars.js"
  ]
}

Dans ./jest/setEnvVars.js:

process.env.SOME_VAR = 'value';

13
Emi 5 déc. 2019 à 11:26

Vous pouvez utiliser la fonctionnalité setupFiles de jest config. Comme l'indique la documentation,

Une liste de chemins d'accès aux modules qui exécutent du code à configurer ou à installer l'environnement de test. Chaque setupFile sera exécuté une fois par test . Étant donné que chaque test s'exécute dans son propre environnement, ces scripts être exécuté dans l'environnement de test immédiatement avant l'exécution le code de test lui-même.

  1. npm install dotenv dotenv qui utilise pour accéder à la variable env.
  2. Créez votre fichier .env dans le répertoire racine de votre application et ajoutez-y cette ligne.
#.env
APP_PORT=8080
  1. Créez votre fichier de module personnalisé comme son nom est someModuleForTest.js et ajoutez-y cette ligne.
//someModuleForTest.js
require("dotenv").config()
  1. Mettez à jour votre fichier jest.config.js comme ceci
module.exports = {
  setupFiles: ["./someModuleForTest"]
}
  1. Vous pouvez accéder à la variable d'env dans tous les blocs de test.
test("Some test name", () => {
  expect(process.env.APP_PORT).toBe("8080")
})
16
Serhan C. 15 sept. 2019 à 13:15

Le setupFiles de Jest est la bonne façon de gérer cela, et vous n'avez pas besoin d'installer dotenv, ni d'utiliser de fichier .env pour le faire fonctionner.

jest.config.js:

module.exports = {
  setupFiles: ["<rootDir>/.jest/setEnvVars.js"]
};

.jest/setEnvVars.js:

process.env.MY_CUSTOM_TEST_ENV_VAR = 'foo'

C'est ça.

21
zgreen 20 nov. 2019 à 11:31

Selon la façon dont vous pouvez organiser votre code, une autre option peut être de placer la variable env dans une fonction exécutée au moment de l'exécution.

Dans ce fichier, la variable d'environnement est définie au moment de l'importation et nécessite des require dynamiques afin de tester différentes variables d'environnement (comme décrit dans cette réponse):

const env = process.env.MY_ENV_VAR;

const envMessage = () => `MY_ENV_VAR is set to ${env}!`;

export default myModule;

Dans ce fichier, la variable d'environnement est définie au moment de l'exécution de envMessage, et vous devriez pouvoir muter process.env directement dans vos tests:

const envMessage = () => {
  const env = process.env.MY_VAR;
  return `MY_ENV_VAR is set to ${env}!`;
}

export default myModule;

Test de plaisanterie:

const vals = [
  'ONE',
  'TWO',
  'THREE',
];

vals.forEach((val) => {
  it(`Returns the correct string for each ${val} value`, () => {
    process.env.MY_VAR = val;

    expect(envMessage()).toEqual(...
3
RobW 10 sept. 2018 à 17:48

https://github.com/facebook/jest/blob/master/packages/jest-cli/bin/jest.js#L12-L14

Rechercher sur node_module / jest-cli / bin / jest.js

#!/usr/bin/env node
/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const importLocal = require('import-local');

if (!importLocal(__filename)) {
  if (process.env.NODE_ENV == null) {
    process.env.NODE_ENV = 'test';
  }

require('../build/cli').run();
}
0
Ismael Fdez 4 mai 2020 à 02:46