使用Jest

时间:2017-12-30 12:14:21

标签: node.js testing environment-variables jestjs

我的应用程序依赖于环境变量,如:

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

我想测试一下,例如:

  • APP_PORT可以通过节点env变量设置。
  • express应用程序正在使用process.env.APP_PORT
  • 的端口集上运行

我怎样才能通过Jest实现这一目标?我可以在每次测试之前设置这些process.env变量,还是应该以某种方式模拟它?

10 个答案:

答案 0 :(得分:26)

我这样做can be found in this SO question

在每次测试之前对resetModules很重要,然后在测试中动态导入模块:

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

答案 1 :(得分:8)

您可以使用Jest Config的setupFiles功能。就像documentation said那样,

  

运行一些代码以配置或设置的模块的路径列表   测试环境。 每个setupFile将在每次测试中运行一次   文件。。由于每个测试都在自己的环境中运行,因此这些脚本将   在执行之前立即在测试环境中执行   测试代码本身。

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

答案 2 :(得分:2)

扩展Serhan C.的答案(https://stackoverflow.com/a/57944454/2708174)...

根据此博客https://tekloon.dev/using-dotenv-with-jest 您可以直接将"dotenv/config"包含在setupFiles中,而不必创建和引用调用require("dotenv").config()的外部脚本。

即简单地

module.exports = {
    setupFiles: ["dotenv/config"]
}

答案 3 :(得分:1)

根据组织代码的方式,另一种选择是将env变量放入运行时执行的函数中。

在此文件中,env var在导入时设置,并且需要动态require才能测试不同的env var(如this answer中所述):

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

答案 4 :(得分:1)

另一种选择是将其添加到jest.config.js定义之后的module.exports文件中:

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

通过这种方式,不必在每个ENV文件中定义.spec变量,并且可以全局对其进行调整。

答案 5 :(得分:1)

Jest的setupFiles是处理此问题的正确方法,您无需安装dotenv,也不需要使用.env文件来使其正常工作。

jest.config.js

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

.jest/setEnvVars.js

process.env.MY_CUSTOM_TEST_ENV_VAR = 'foo'

就是这样。

答案 6 :(得分:0)

我想您也可以尝试以下方法:

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

// test code...

process.env = currentEnv;

这对我有用,您不需要模块内容

答案 7 :(得分:0)

./package.json中:

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

./jest/setEnvVars.js中:

process.env.SOME_VAR = 'value';

答案 8 :(得分:0)

在我看来,如果将对环境变量的检索提取到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', () => {...});

答案 9 :(得分:0)

在测试文件中:

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

./package.json的测试脚本中:

"scripts": {
   "test": "jest --setupFiles dotenv/config",
 }

./env中:

APP_PORT=8080