为啥我的模块没有出现在 require.cache 中?

Posted

技术标签:

【中文标题】为啥我的模块没有出现在 require.cache 中?【英文标题】:Why is my module not appearing in require.cache?为什么我的模块没有出现在 require.cache 中? 【发布时间】:2017-02-20 07:21:46 【问题描述】:

操作系统:Windows 10 节点版本:0.10.36 摩卡全球版:1.21.4

我正在尝试使用 mocha 对我的代码进行单元测试,但我尝试测试的代码中的一个局部变量在测试之间持续存在,从而导致问题。

当我查看 require.cache 内部时,在测试之间,我看不到我的模块。我的理解是,如果我想在测试之间重置此模块,我应该清除缓存。

我做了一个小节点项目来演示这个问题:

package.js:


    "name": "cache-test",
    "version": "0.0.1",
    "dependencies": 
        "lodash": "4.5.0"
    ,
    "devDependencies": 
        "chai": "1.9.2",
        "mocha": "1.21.4",
        "mockery": "1.4.0",
        "sinon": "1.10.3",
        "app-root-path":"*"
    

module.js:

var foo = "default value";

exports.init = function()
    foo = 'init';


exports.returnFoo = function()
    return foo;

test/test-module.js

var chai = require("chai"),
    expect = chai.expect,
    mockery = require("mockery"),
    appRoot = require('app-root-path');


var module;

describe("module", function () 

    before(function () 
        mockery.enable( useCleanCache: true );
    );

    beforeEach(function () 
        mockery.registerAllowable(appRoot + "/module", true);
        module = require(appRoot + "/module");
    );

    afterEach(function () 
        console.log('deleting', require.cache[require.resolve(appRoot + "/module")]);
        delete require.cache[require.resolve(appRoot + "/module")];
        module = null;
        mockery.deregisterAll();
    );

    after(function () 
        mockery.disable();
    );

    describe("test",function()
        it("foo should be 'init' after running init()",function()
            module.init();
            console.log('foo is ',module.returnFoo());
            expect(module.returnFoo()).to.equal('init');
        );

        it("foo should be 'default value' if init() is not run",function()
            console.log('foo is ',module.returnFoo());
            expect(module.returnFoo()).to.equal("default value");
        );
    );
);

运行mocha 打印

  module
    test
foo is  init
      √ foo should be 'init' after running init()
deleting undefined
foo is  init
  1 failing

【问题讨论】:

【参考方案1】:

哦,我需要添加

mockery.resetCache() 到我的afterEach 函数。这样就解决了。

似乎useCleanCache 选项和从require.cache 中删除条目不兼容,因为前者会阻止它出现在后者中。

所以它是:

不要使用 useCleanCache 从 require.cache 中“手动”删除它

使用 useCleanCache 使用resetCache()

但不要试图混搭。

【讨论】:

是的,谢谢你,这两个选项混合在一起会做一些奇怪的事情

以上是关于为啥我的模块没有出现在 require.cache 中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 Typescript 的 .net 核心项目中的 NPM 模块出现此错误?

为啥我的 Laravel 模块中出现“找不到类”错误?

为啥我的电脑一开机会出现模块加载失败的提示?

这个为啥总是显示import turtle出现错误,是没有这个模块吗?

Globals模块常用的方法和属性

当我使用节点启动机器人时,为啥 discord.js 模块出现错误?