Search code examples
node.jsmocha.jsmockery

Why is my module not appearing in require.cache?


OS: Windows 10
Node version: 0.10.36
Mocha global version: 1.21.4

I'm attempting to use mocha to unit-test my code, but a local variable inside the code I'm trying to test is persisting between tests, causing problems.

When I look inside require.cache, between tests, I don't see my module in there. It is my understanding that I should be clearing the cache if I want to reset this module between tests.

I made a small node project to demonstrate this issue:

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

running mocha prints

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

Solution

  • Oh, I needed to add

    mockery.resetCache() to my afterEach function. That solved it.

    It seems like the useCleanCache option, and deleting the entry from require.cache aren't compatible with each-other, as the former keeps it from appearing in the latter.

    So it's either:

    • Don't use useCleanCache
    • Delete it "manually" from require.cache

    OR

    • Use useCleanCache
    • Use resetCache()

    but don't attempt to mix and match.