使用.env文件进行单元测试,并使用jest

Ron*_*ley 17 javascript unit-testing environment-variables jestjs

是否可以从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();
    });
});
Run Code Online (Sandbox Code Playgroud)

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

但是,通过阅读文档, Jest不会通过webpack运行测试; 而是通过moduleNameMapper模拟出模块.这适用于其他一切,但我无法加载env文件变量.到目前为止,我已经尝试将setupFiles选项用于调用dotenv.config的js文件,其中包含给定的env文件的路径,如下所示:

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

这不起作用,所以我现在只使用.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';
Run Code Online (Sandbox Code Playgroud)

bob*_*ito 27

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

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

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

"scripts": {
  "test": "DOTENV_CONFIG_PATH=.env.test jest --setupFiles=dotenv/config"
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*han 12

您可以像这样为所有测试加载 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'});
Run Code Online (Sandbox Code Playgroud)


li *_*i x 7

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


ZYi*_*nMD 7

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

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

Run Code Online (Sandbox Code Playgroud)
  1. 使用globalSetupglobalTeardown:非常类似于 1。

  2. 只需使用“全局变量”(不能更改process.env,但可能足以满足您的需要):

// jest.config.json:
{
  "globals": {
    "a": 1
  }
}
// test:
test('global', () => {
  expect(global.a).toBe(1);
});
Run Code Online (Sandbox Code Playgroud)

反对使用的原因dotenv是里面的环境变量process.env在不同的部署之间是不同的,不是你设置的。如果一个变量在不同的环境中没有变化,那么它就不是环境变量,它只是你手动设置的全局变量。dotenv 文档进一步指出了 12 因子应用程序,这是一个很好的阅读。

  • 我没有看到任何说明在测试期间不使用的内容。 (2认同)

exa*_*cae 7

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

有用的文章在这里找到。

完整设置:


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;
Run Code Online (Sandbox Code Playgroud)


The*_*der 6

这些都不适合我,但是我在package.json的Jest中找到了一篇很棒的文章,关于如何默认配置dotenv

{
  "scripts": {
    "test": "jest --setupFiles dotenv/config"
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您像我一样试图找到一种方法来更改 dotenv 配置路径以使用“.env.test”而不是“.env”,那么当您运行 jest 时,答案是“DOTENV_CONFIG_PATH=./.env.test jest”。 (19认同)
  • 是的,无需制作单独的安装文件。如果您有现有的`jest.config.js`,您也可以将其添加到那里:`module.exports = { setupFiles: ['dotenv/config'] }` (5认同)

Ron*_*ley 5

所以这个问题需要改变这个:

dotenv.config({ path: './env' });
Run Code Online (Sandbox Code Playgroud)

到 :

dotenv.config();
Run Code Online (Sandbox Code Playgroud)

为什么它没有捡起来我不知道,但只是保留默认值。

  • 你是不是漏掉了一点?`dotenv.config({ 路径: './.env' });` (6认同)