Jestでprocess.envをテストします


115

私は次のような環境変数に依存するアプリを持っています:

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

そして私はそれを例えばテストしたいと思います:

  • APP_PORTは、ノードの環境変数で設定できます。
  • または、expressアプリがで設定されたポートで実行されていることprocess.env.APP_PORT

Jestでこれを達成するにはどうすればよいですか?process.env各テストの前にこれらの変数を設定できますか、それとも何らかの方法でモックする必要がありますか?


はい、環境変数を設定できます
Deep Kakkar 2017

@Deep AFAIK jestconfigで一度だけ設定できます。
Tomasz Mularczyk 2017

回答:


155

私がそれをした方法は、このSOの質問で見つけることができます

各テストの前にModulesリセットしてから、テスト内でモジュールを動的にインポートすることが重要です。

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
  });
});

Jestを実行する前にenv値をロードする方法を探す場合は、以下答えを探してください。そのためにはsetupFilesを使用する必要があります。


2
完全な回答を提供してください
Yves M.

私にとってはうまくいきました。デフォルトのエクスポートを使用する必要がある場合は、次のようにすることができます。consttestsModule = require( '../../ config / env')。default;
アジズ

6
これがうまくいかない場合は、実際のコードでenv変数を読み取るときに、グローバル変数がprocess.env.YOUR_VARIABLEを指すのではなく、関数/制限付きスコープで読み取るようにしてください。
penguinsource

1
@learnerは、私が正しく覚えていればdelete process.env.NODE_ENV; 、私のコードの残り物であり、あなたの場合は問題ではありません。重要なのはjest.resetModules()、テストの前と後に呼び出して、最初のprocess.envオブジェクト(OLD_ENV)を復元することです
Tomasz Mularczyk

1
@MEMark元のオブジェクトを変更しないためにコピーを作成する必要があります(後で復元する必要があります)
Tomasz Mularczyk

60

Jest'ssetupFilesはこれを処理する適切な方法であり、それを機能させるためにインストールdotenvしたり、.envファイルを使用したりする必要はありません。

jest.config.js

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

.jest/setEnvVars.js

process.env.MY_CUSTOM_TEST_ENV_VAR = 'foo'

それでおしまい。


1
これは、jestで環境変数を処理する最も簡単な方法です。ありがとうございます。
klaevv

26

./package.json

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

./jest/setEnvVars.js

process.env.SOME_VAR = 'value';


2
おそらく私が見た中で最も簡単な方法です。dotenvパッケージをインストールする必要はありません。
MattC

23

setupFilesjestconfigの機能を使用できます。ドキュメントと述べているが、

テスト環境を構成またはセットアップするためのコードを実行するモジュールへのパスのリスト。各setupFileは、テストファイルごとに1回実行されます。すべてのテストは独自の環境で実行されるため、これらのスクリプトは、テストコード自体を実行する直前にテスト環境で実行されます。

  1. npm install dotenv 環境変数へのアクセスに使用するdotenv。
  2. .envアプリケーションのルートディレクトリにファイルを作成し、この行を追加します。
#.env
APP_PORT=8080
  1. someModuleForTest.jsという名前のカスタムモジュールファイルを作成し、この行を追加します。
//someModuleForTest.js
require("dotenv").config()
  1. jest.config.jsこのようにファイルを更新します
module.exports = {
  setupFiles: ["./someModuleForTest"]
}
  1. すべてのテストブロック内でenvの変数にアクセスできます。
test("Some test name", () => {
  expect(process.env.APP_PORT).toBe("8080")
})

10

別のオプションはjest.config.jsmodule.exports定義後にファイルに追加することです。

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

このようにENV、各.specファイルで変数を定義する必要はなく、グローバルに調整できます。


これは素晴らしい答えです。ありがとうございました。
spierce7

3

コードを整理する方法に応じて、実行時に実行される関数内にenv変数を配置するという別のオプションがあります。

このファイルでは、env varはインポート時に設定され、requireさまざまなenv varをテストするために動的なsが必要です(この回答で説明されているように)。

const env = process.env.MY_ENV_VAR;

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

export default myModule;

このファイルでは、env varはenvMessage実行時に設定されており、テストでprocess.envを直接変更できるはずです。

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

export default myModule;

ジェストテスト:

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

私はあなたもこれを試すことができると思います:

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

// test code...

process.env = currentEnv;

これは私にとってはうまくいき、モジュールのものは必要ありません


問題は、process.envを使用する別のファイルをインポートした場合、それを直接変更しても効果がないことです。したがって、各テストの前に、Jestに「このファイルをインポートして再度実行してください」のように伝える必要があります。
TomaszMularczyk19年

0

私の意見では、環境変数の取得をutilに抽出すると(環境変数が設定されていない場合にすばやく失敗するチェックを含める必要があります)、utilをモックするだけではるかにクリーンで理解しやすくなります。 。

// 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', () => {...});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.