【问题标题】:Using .env files for unit testing with jest使用 .env 文件进行单元测试
【发布时间】:2018-10-19 21:43:55
【问题描述】:

是否可以从 env 文件加载环境变量以在 Jest 中进行单元测试?我希望像这样对其进行一系列测试:

// unit tests for env file
describe('env', () => {
    it('should have a client id', () => {
        expect(process.env.CLIENT_ID).toBeDefined();
    });
    it('should have a client secret', () => {
        expect(process.env.CLIENT_SECRET).toBeDefined();
    });
    it('should have a host', () => {
        expect(process.env.HOST).toBeDefined();
    });
    it('should have a scope', () => {
        expect(process.env.SCOPE).toBeDefined();
    });
    it('should have a response type', () => {
        expect(process.env.RESPONSE_TYPE).toBeDefined();
    });
    it('should have a redirect uri', () => {
        expect(process.env.REDIRECT_URI).toBeDefined();
    });
});

目前,上述所有测试都将失败,说明变量未定义。最初我使用的是 mocha/chai 设置,它允许我通过使用 dotenv 加载我的所有 env 变量。这涉及通过 webpack 运行所有单元测试并且工作正常。

然而,阅读documentation Jest 并没有通过 webpack 运行测试;相反,模块是通过 moduleNameMapper 模拟出来的。这适用于其他一切,但我无法加载 env 文件变量。到目前为止,我已经尝试对一个调用 dotenv.config 的 js 文件使用 setupFiles 选项,并使用给它的 env 文件的路径,如下所示:

// setup file for jest
const dotenv = require('dotenv');
dotenv.config({ path: './env' });

这不起作用,所以我现在只使用一个 .env.js 文件进行单元测试,并将这个文件传递给 setupFiles 选项。但是,为了可维护性,并使其与 webpack 一起用于生产,我想将它们全部保存在一个文件中。以下是 .env.js 文件如何查找以供参考的摘录

// .env.js extract example
process.env.PORT = 3000;
process.env.HOST = 'localhost';
process.env.CLIENT_ID = 'your client id';
process.env.REDIRECT_URI = 'your callback endpoint';

【问题讨论】:

  • 使用 Jest 的 setupFiles 和 dotenv.config(...) 是肯定的方法。您使用这种方法遇到的错误是什么?我会仔细检查以确保您的路径正确。我在一个项目中使用dotenv-safe,并在 jest 设置文件中进行初始化,几乎与您所拥有的完全一样。
  • 是的,差不多了,谢谢。无法检查您的评论作为答案,所以我刚刚添加了它。

标签: javascript unit-testing environment-variables jestjs


【解决方案1】:

我找到了另一种使用自定义.env 文件运行 dotenv 玩笑的解决方案。就我而言,我使用 NPM 脚本运行 jest。

  1. 设置 jest 以使用 dotenv(如其他解决方案所示)
jest --setupFiles=dotenv/config
  1. 使用环境变量添加自定义 .env 文件(此处为:.env.test
DOTENV_CONFIG_PATH=.env.test jest --setupFiles=dotenv/config

这可以直接添加到package.json的脚本部分

"scripts": {
  "test": "DOTENV_CONFIG_PATH=.env.test jest --setupFiles=dotenv/config"
}

【讨论】:

  • 很干净的方法,我选这种方式
【解决方案2】:

(2020) 根据dotenv doc,您不应该在测试中使用dotenv。如果您需要的只是一些全局可用的值,则有多种设置方法,例如:

  1. 用 jest 设置全局变量:
// jest.config.json:
{
  "globals": {
    "a": 1
  }
}
// test:
test('global', () => {
  expect(global.a).toBe(1);
});
  1. 使用设置文件:
// jest.config.json:
{
  "setupFiles": ['./jestSetup.js'],
}
// jestSetup.js:
process.env.FOO = 'FOO';
global.bar = 'bar';
// test:
test('env', () => {
  expect(process.env.FOO).toBe('FOO');
  expect(global.bar).toBe('bar');
});

  1. 使用globalSetupglobalTeardown: 与 2 非常相似。

反对使用dotenv 的原因是process.env 在不同的部署中是不同的,这不是你设置的。如果一个变量在不同的环境中没有变化,那么它就不是环境变量,它只是一个你手动设置的全局变量。 dotenv 文档进一步指向the 12 factor app,这是一本很好的读物。

【讨论】:

  • 很好的答案。我还要补充一点,通过环境变量的测试可能没用
  • 我没有看到任何说明在测试期间不使用的内容。
  • @AlfredoR 它说不能超过一个,并给出.env.test 作为不做什么的明确示例。
  • @MEMark 如果你坚持一些不是标准的东西,你最终会限制你的选择。该规则适用于部署环境,但我认为将 diff .env 文件用于 diff 本地开发目的(例如单元或集成测试)并没有什么害处。
  • @AlfredoR 我个人倾向于同意你的观点。但是链接到的文章不同意这种观点。
【解决方案3】:

您可以像这样为所有测试加载 env 文件。每个加载的测试文件都会执行一次设置文件。

jest.config.js : 

module.exports = {
 ....
    setupFiles: ["<rootDir>/test/setup-tests.ts"]
}


test/setup-tests.ts:

import dotenv from 'dotenv';
dotenv.config({path: './config.env.test'});

【讨论】:

  • 这太完美了?
【解决方案4】:

将这里的几个答案组合成一个简单的解决方案:添加 dotenv-flow 并在您的测试脚本中使用它:

jest --setupFiles dotenv-flow/config

【讨论】:

    【解决方案5】:

    在 jest.config.ts 中添加 setupFiles: ['dotenv/config'] 对我有用。

    发现有用的文章here

    完整设置:

    
    const jestConfig = {
        preset: 'ts-jest',
        globals: {
            'ts-jest': {
                tsconfig: '<rootDir>/tsconfig.spec.json',
            },
        },
        verbose: true,
        testMatch: ['<rootDir>/test/**/*(*.)+(test).+(tsx)'],
        setupFiles: [
            'dotenv/config'
        ],
        setupFilesAfterEnv: ['<rootDir>/test/setupTests.ts'],
        moduleFileExtensions: ['js', 'ts', 'tsx'],
        collectCoverage: true,
        coverageDirectory: 'target/coverage',
        collectCoverageFrom: [
            'src/**/*.tsx',
        ],
        moduleNameMapper: {
            '^.+\\.(css)$': 'identity-obj-proxy',
            '^.+\\.(png|svg|pdf|jpg|jpeg)$': 'jest-transform-stub'
        },
        transform: {
            '^.+\\.(js|jsx)$': 'babel-jest',
        },
        transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$'],
    };
    
    export default jestConfig;
    

    【讨论】:

      【解决方案6】:

      我有点晚了,但希望这对正在寻找使 dotenv 工作的人有所帮助。这只是@DavidDehghan 所说的扩展风味。 因此,像大卫所说的那样,在任何开玩笑的配置之前添加一个要运行的设置文件

      现在确保为平台加载dotenv来解析相对路径,请使用path模块来解析文件夹

      import * as  dotenv from 'dotenv';
      import * as path from 'path';
      
      dotenv.config({ path: path.resolve(__dirname + './../config/testFolder/.env') });
      

      现在在您的规范文件中,您可以测试process.env 变量是否包含从testFolder 中的.env 文件加载的值

      describe('Test suite - testing app service', () => {
        beforeAll(() => {
          console.log('coming inside beforeAll', process.env.LCp);
      
        });
      });
      

      【讨论】:

        【解决方案7】:

        这些都不适合我,但我在 package.json 中找到了一篇关于 configuring dotenv by default in Jest 的精彩文章:

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

        【讨论】:

        • 是的,没有必要制作单独的安装文件。如果您有一个现有的jest.config.js,您也可以在其中添加它:module.exports = { setupFiles: ['dotenv/config'] }
        • 如果你像我一样试图找到一种方法来改变 dotenv 配置路径以使用.env.test 而不是.env,当你运行 jest 时答案是DOTENV_CONFIG_PATH=./.env.test jest
        【解决方案8】:

        您使用./ 的顶级配置路径从注入点来看是相对的,您的测试套件可能位于名为test 的文件夹中,这会导致在运行单元测试时找不到它。 dotenv.config(); 使用类似于绝对路径的全局注入策略。

        【讨论】:

        • 啊,很好的解释。谢谢!
        • 拯救了我的一天!非常感谢!
        【解决方案9】:

        所以问题需要改变这个:

        dotenv.config({ path: './env' });
        

        到:

        dotenv.config();
        

        我不知道为什么它没有启动它,但只是保留默认设置。

        【讨论】:

        • 你没有漏掉一点吗? dotenv.config({ path: './.env' });
        • 哦,你这个双关语?
        猜你喜欢
        • 1970-01-01
        • 2015-09-18
        • 2010-09-15
        • 1970-01-01
        • 2019-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多