test process.env mit Jest


101

Ich habe eine App, die von Umgebungsvariablen abhängt wie:

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

und ich möchte das zum Beispiel testen:

  • APP_PORT kann durch die Variable env des Knotens festgelegt werden.
  • oder dass eine expressApp auf dem Port ausgeführt wird, mit dem festgelegt wurdeprocess.env.APP_PORT

Wie kann ich das mit Jest erreichen? Kann ich diese process.envVariablen vor jedem Test festlegen oder sollte ich sie vielleicht irgendwie verspotten?


Ja, Sie können die Umgebungsvariable setzen
Deep Kakkar

@ Deep AFAIK Ich kann sie nur einmal in der Scherzkonfiguration einstellen.
Tomasz Mularczyk

Antworten:


134

Die Art und Weise, wie ich es getan habe, kann in dieser SO-Frage gefunden werden .

Es ist wichtig, die Module vor jedem Test zurückzusetzen und das Modul dann dynamisch in den Test zu importieren:

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

  beforeEach(() => {
    jest.resetModules() // most important - it clears the cache
    process.env = { ...OLD_ENV }; // make a copy
  });

  afterAll(() => {
    process.env = OLD_ENV; // restore 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
  });
});

Wenn Sie nach einer Möglichkeit suchen, env-Werte zu laden, bevor Sie den Jest ausführen, suchen Sie nach der folgenden Antwort . Sie sollten dafür setupFiles verwenden .


2
Bitte geben Sie die vollständige Antwort
Yves M.

Hat super für mich funktioniert. Wenn Sie einen Standardexport verwenden müssen, können Sie Folgendes tun: const testingModule = require ('../../ config / env'). Default;
Aziz

6
Falls dies bei Ihnen nicht funktioniert, stellen Sie sicher, dass Sie die env-Variable in Ihrem tatsächlichen Code in einer Funktion / einem begrenzten Bereich lesen, anstatt dass globale Variablen auf process.env.YOUR_VARIABLE verweisen.
Penguinsource

1
@learner, wenn ich mich richtig erinnere, delete process.env.NODE_ENV; ist nur ein Überbleibsel aus meinem Code und sollte in Ihrem Fall keine Rolle spielen. Was zählt, ist, dass Sie jest.resetModules()vor dem Test aufrufen und danach das ursprüngliche process.env-Objekt (OLD_ENV) wiederherstellen
Tomasz Mularczyk

1
@MEMark Sie müssen eine Kopie erstellen, um das ursprüngliche Objekt nicht zu mutieren (das Sie später wiederherstellen müssen)
Tomasz Mularczyk

51

Jest's setupFilesist der richtige Weg, um damit umzugehen, und Sie müssen weder ein installieren dotenvnoch ein verwenden.env Datei , damit sie funktioniert.

jest.config.js::

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

.jest/setEnvVars.js::

process.env.MY_CUSTOM_TEST_ENV_VAR = 'foo'

Das ist es.


Dies ist der einfachste Weg, um env-Variablen im Scherz zu behandeln, danke!
klaevv

22

In ./package.json:

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

In ./jest/setEnvVars.js:

process.env.SOME_VAR = 'value';

2
Wahrscheinlich der einfachste Weg, den ich gesehen habe. Das dotenv-Paket muss nicht installiert werden.
MattC

21

Sie können die setupFilesFunktion der Scherzkonfiguration verwenden. Wie die Dokumentation sagte ,

Eine Liste von Pfaden zu Modulen, auf denen Code zum Konfigurieren oder Einrichten der Testumgebung ausgeführt wird. Jede setupFile wird einmal pro Testdatei ausgeführt. Da jeder Test in einer eigenen Umgebung ausgeführt wird, werden diese Skripte unmittelbar vor der Ausführung des Testcodes in der Testumgebung ausgeführt.

  1. npm install dotenv dotenv, mit dem auf die env-Variable zugegriffen wird.
  2. Erstellen Sie Ihre .envDatei im Stammverzeichnis Ihrer Anwendung und fügen Sie diese Zeile hinzu.
#.env
APP_PORT=8080
  1. Erstellen Sie Ihre benutzerdefinierte Moduldatei mit dem Namen someModuleForTest.js und fügen Sie diese Zeile hinzu.
//someModuleForTest.js
require("dotenv").config()
  1. Aktualisieren Sie Ihre jest.config.jsDatei wie folgt
module.exports = {
  setupFiles: ["./someModuleForTest"]
}
  1. Sie können in allen Testblöcken auf die Variable von env zugreifen.
test("Some test name", () => {
  expect(process.env.APP_PORT).toBe("8080")
})

6

Eine andere Möglichkeit besteht darin, es jest.config.jsnach der module.exportsDefinition zur Datei hinzuzufügen :

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

Auf diese Weise müssen die ENVVariablen nicht in jeder .specDatei definiert werden, und sie können global angepasst werden.


3

Abhängig davon, wie Sie Ihren Code organisieren können, kann eine andere Option darin bestehen, die env-Variable in eine Funktion einzufügen, die zur Laufzeit ausgeführt wird.

In dieser Datei wird die env-Variable zum Zeitpunkt des Imports festgelegt und erfordert dynamische requires, um verschiedene env-Variablen zu testen (wie in dieser Antwort beschrieben ):

const env = process.env.MY_ENV_VAR;

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

export default myModule;

In dieser Datei wird die env var zur envMessageAusführungszeit festgelegt, und Sie sollten in der Lage sein, process.env direkt in Ihren Tests zu mutieren:

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

export default myModule;

Scherztest:

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(...

0

Ich denke, Sie könnten das auch versuchen:

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

// test code...

process.env = currentEnv;

Das funktioniert bei mir und Sie brauchen keine Modulsachen


Das Problem ist, dass wenn Sie eine andere Datei importieren, die process.env verwendet, eine direkte Änderung keine Auswirkungen hat. Vor jedem Test müssen Sie Jest also Folgendes mitteilen: "Hey, importieren Sie diese Datei und führen Sie sie erneut aus."
Tomasz Mularczyk

0

Meiner Meinung nach ist es viel sauberer und verständlicher, wenn Sie das Abrufen von Umgebungsvariablen in ein Util extrahieren (Sie möchten wahrscheinlich eine Überprüfung einschließen, die schnell fehlschlägt, wenn eine Umgebungsvariable sowieso nicht festgelegt ist), dann können Sie das Util einfach verspotten .

// util.js
exports.getEnv = (key) => {
    const value = process.env[key];
    if (value === undefined) {
      throw new Error(`Missing required environment variable ${key}`);
    }
    return value;
};

// app.test.js
const util = require('./util');
jest.mock('./util');

util.getEnv.mockImplementation(key => `fake-${key}`);

test('test', () => {...});

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.