使用 Jest 时使节点缓存无效
Posted
技术标签:
【中文标题】使用 Jest 时使节点缓存无效【英文标题】:Invalidate node cache when using Jest 【发布时间】:2018-06-11 01:13:48 【问题描述】:我有一个包含 process.env
属性的对象的文件:
env.js
console.log('LOADING env.js');
const
PROXY_PREFIX = '/api/',
USE_PROXY = 'true',
APP_PORT = '8080',
API_URL = 'https://api.address.com/',
NODE_ENV = 'production',
= process.env;
const ENV =
PROXY_PREFIX,
USE_PROXY,
APP_PORT,
API_URL,
NODE_ENV,
;
module.exports.ENV = ENV;
现在我尝试用不同的process.env
属性测试这个文件:
env.test.js
const envFilePath = '../../config/env';
describe('environmental variables', () =>
const OLD_ENV = process.env;
beforeEach(() =>
process.env = ...OLD_ENV ;
delete process.env.NODE_ENV;
);
afterEach(() =>
process.env = OLD_ENV;
);
test('have default values', () =>
const ENV = require(envFilePath);
expect(ENV).toMatchSnapshot();
);
test('are string values (to avoid casting errors)', () =>
const ENV = require(envFilePath);
Object.values(ENV).forEach(val => expect(typeof val).toEqual('string'));
);
test('will receive process.env 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 ENV = require(envFilePath);
expect(ENV.NODE_ENV).toEqual('dev');
expect(ENV.PROXY_PREFIX).toEqual('/new-prefix/');
expect(ENV.API_URL).toEqual('https://new-api.com/');
expect(ENV.APP_PORT).toEqual('7080');
expect(ENV.USE_PROXY).toEqual('false');
);
);
不幸的是,即使我尝试在每个测试中分别加载文件,文件也只加载一次,导致第三次测试失败:
Expected value to equal: "dev" Received: "production"
附:当我单独运行测试时它不会失败。
我也知道 env.js 只加载一次,因为 console.log('LOADING env.js');
只被触发一次。
我试图使节点缓存失效,例如:
beforeEach(() =>
delete require.cache[require.resolve(envFilePath)];
process.env = ...OLD_ENV ;
delete process.env.NODE_ENV;
);
但在每次测试之前require.cache
是空的,所以似乎 Jest 以某种方式负责导入文件。
我也尝试运行yarn jest --no-cache
,但没有帮助。
所以我想要的是在每次测试之前加载 env.js,这样我就可以测试它在不同节点环境变量下的表现。
jest@^22.0.4
【问题讨论】:
您使用的是哪个版本的jest
?
@Prakashsharma 22.0.4
尝试在beforeEach
中使用jest.resetModules()
。 facebook.github.io/jest/docs/en/…
@Prakashsharma 谢谢你!发表答案,我会接受。奇怪的是我错过了。
【参考方案1】:
您可以在beforeEach
方法中使用jest.resetModules()
来重置已经需要的模块
beforeEach(() =>
jest.resetModules()
process.env = ...OLD_ENV ;
delete process.env.NODE_ENV;
);
【讨论】:
【参考方案2】:您可以使用jest.isolateModules(fn)
单独要求模块,而不是重置所有模块。
例如:
test('are string values (to avoid casting errors)', () =>
jest.isolateModules(() =>
const ENV = require(envFilePath);
Object.values(ENV).forEach(val => expect(typeof val).toEqual('string'));
);
);
【讨论】:
以上是关于使用 Jest 时使节点缓存无效的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Jest 不让我使用节点测试环境,即使他们自己更改了它?