从node.js文档中:
第一次加载模块后将对其进行缓存。这意味着(除其他事项外)每次对require('foo')的调用都将获得与返回的对象完全相同的对象(如果它将解析为相同的文件)。
有没有办法使该缓存无效?即对于单元测试,我希望每个测试都可以在一个新对象上进行。
从node.js文档中:
第一次加载模块后将对其进行缓存。这意味着(除其他事项外)每次对require('foo')的调用都将获得与返回的对象完全相同的对象(如果它将解析为相同的文件)。
有没有办法使该缓存无效?即对于单元测试,我希望每个测试都可以在一个新对象上进行。
我会再向luff的答案添加一行,并更改参数名称:
function requireCached(_module){
var l = module.children.length;
for (var i = 0; i < l; i++)
{
if (module.children[i].id === require.resolve(_module))
{
module.children.splice(i, 1);
break;
}
}
delete require.cache[require.resolve(_module)];
return require(_module)
}
我不能100%地确定“无效”是什么意思,但是您可以在require
语句上方添加以下内容以清除缓存:
Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })
从@ Dancrumb的评论采取这里
对于使用Jest的任何人,因为Jest进行自己的模块缓存,所以有一个内置函数-只需确保jest.resetModules
运行例如。在每个测试之后:
afterEach( function() {
jest.resetModules();
});
尝试使用decache就像建议另一个答案后,发现了这一点。感谢Anthony Garvan。
功能文档在这里。
rewire非常适合此用例,每次调用都会获得一个新实例。轻松的依赖注入,用于node.js单元测试。
rewire在模块中添加了一个特殊的setter和getter,因此您可以修改它们的行为以进行更好的单元测试。你可以
为其他模块或全局变量(例如进程泄漏专用变量)注入模拟,将覆盖模块内的变量。rewire不会加载文件并评估内容以模拟节点的require机制。实际上,它使用节点自身的要求来加载模块。因此,您的模块在测试环境中的行为与常规情况下完全一样(修改除外)。
对所有咖啡因上瘾者来说是个好消息:rewire也可以在Coffee-Script中使用。请注意,在这种情况下,需要在devDependencies中列出CoffeeScript。
如果用于单元测试,则另一个好的工具是proxyquire。每次您代理查询模块时,它将使模块缓存无效并缓存一个新的模块。它还允许您修改要测试的文件所需的模块。