我的应用程序依赖于环境变量,如:
const APP_PORT = process.env.APP_PORT || 8080;
我想测试一下,例如:
express
应用程序正在使用process.env.APP_PORT
我怎样才能通过Jest实现这一目标?我可以在每次测试之前设置这些process.env
变量,还是应该以某种方式模拟它?
答案 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将在每次测试中运行一次 文件。。由于每个测试都在自己的环境中运行,因此这些脚本将 在执行之前立即在测试环境中执行 测试代码本身。
npm install dotenv
dotenv,用于访问环境变量。.env
文件,并将此行添加到其中。#.env
APP_PORT=8080
//someModuleForTest.js
require("dotenv").config()
jest.config.js
文件module.exports = {
setupFiles: ["./someModuleForTest"]
}
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