node.jsunit-testingsinonproxyquire

Proxyquire: Cannot Stub fs.readFileSync


I seem unable to stub readFileSync on fs from the NodeJS core. The following code isolates the issue. Running the test via Mocha results in the following:

> mocha tests/test.js

      Some description
        1) "before all" hook


      0 passing (15ms)
      1 failing

      1) Some description "before all" hook:
         TypeError: Cannot read property 'charCodeAt' of undefined
          at Object.stripBOM (internal/module.js:48:14)
          at Object.require.extensions.(anonymous function) (node_modules/proxyquire/lib/proxyquire.js:276:43)
          at Proxyquire._withoutCache (node_modules/proxyquire/lib/proxyquire.js:179:12)
          at Proxyquire.load (node_modules/proxyquire/lib/proxyquire.js:136:15)
          at Context.<anonymous> (tests/test.js:12:15)

Here's tests/test.js

var proxyquire = require('proxyquire'),
    sinon = require('sinon'),
    fs = require('fs'),
    sut;

describe('Some description', function () {
    var readFileSyncStub;

    before(function () {
        readFileSyncStub = sinon.stub(fs, 'readFileSync');
        readFileSyncStub.withArgs('someFile.js', { encoding: 'utf8' }).returns('some text');
        sut = proxyquire('../sut', { fs: { readFileSync: readFileSyncStub } }); // Exception encountered somewhere in here ...
    });

    after(function () {
        fs.readFileSync.restore(); // This is executed ...
    });

    it('Some it', function () {
        // This never happens ...
    });
});

And here's sut.js, which is the module being tested:

var fs = require('fs'); // The code in this file is never executed ...

module.exports = function () {
    return fs.readFileSync('someFile.js', { encoding: 'utf8' });
};

The folder structure for the project is:

./sut.js
./package.json
./tests/test.js

test.js can be run by executing mocha tests/test.js from the prompt.

I noticed that several years ago there was an issue reported on Github about something that looks similar, but I can't tell if it's the same issue, or a different one. Here's the link:

https://github.com/thlorenz/proxyquire/issues/12

In case it helps, these are the dependencies in my package.json file. I tried using similar versions to the dependencies for proxyquire:

{
  ...
  "devDependencies": {
    "jshint": "^2.9.5",
    "jslint": "^0.11.0",
    "mocha": "~3.1",
    "proxyquire": "^1.8.0",
    "sinon": "~1.9"
  },
  "dependencies": {}
  ...
}

Any help is much appreciated!


Solution

  • You don't need to stub fs.readFileSync() if you're also using proxyquire to replace it (in fact, stubbing fs.readFileSync() is causing your problem, because it's breaking both require() and proxyquire).

    Try this:

    describe('Some description', function () {
      var readFileSyncStub;
    
      before(function() {
        readFileSyncStub = sinon.stub()
                                .withArgs('someFile.js', { encoding: 'utf8' })
                                .returns('some text');
        sut = proxyquire('../sut', { fs : { readFileSync : readFileSyncStub } });                         
      });
    
      it('Some it', function () {
        let value = sut();
        assert.equal(value, 'some text');
      });
    
    });