1

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!

Andrew
  • 6,144
  • 10
  • 37
  • 54

1 Answers1

5

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

});
robertklep
  • 198,204
  • 35
  • 394
  • 381
  • Thanks @robertklep, that works great! I'm a little confused, though. The examples on Github are stubbing the methods for fs: https://github.com/thlorenz/proxyquire/blob/master/examples/sinon/foo-tests.js. – Andrew Jul 18 '17 at 21:52
  • 2
    @Andrew those examples are old (5 years for that particular file). I guess that in the meantime, Node.js internals have changed. Merely stubbing `fs.readFileSync()` causes things to break in recent Node.js versions. – robertklep Jul 19 '17 at 06:26
  • how will I be able to assert that readFileSyncStub was called in this case ? Can I do sinon.assert.calledOnce or sinon.assert.calledExactly with on readFileSyncStub ? – Novice Mar 20 '20 at 03:10
  • @Novice did you try? ;D – robertklep Mar 20 '20 at 13:28