How do I stub node.js built-in fs during testing?
Stubs are functions/programs that simulate the behaviors of components/modules. Stubs provide canned answers to function calls made during test cases.
An example can be writing a file, without actually doing so.
var fs = require('fs')
var writeFileStub = sinon.stub(fs, 'writeFile', function (path, data, cb) {
return cb(null)
})
expect(writeFileStub).to.be.called
writeFileStub.restore()
Rewire and other stubbing solutions are good if the module under test is the one making calls to fs
itself. However, if the module under test uses a library which uses fs
underneath, rewire and other stubbing solution get hairy pretty quickly.
There is a better solution now: mock-fs
The mock-fs module allows Node's built-in
fs
module to be backed temporarily by an in-memory, mock file system. This lets you run tests against a set of mock files and directories instead of lugging around a bunch of test fixtures.
Example (shamelessly lifted from its readme):
var mock = require('mock-fs');
mock({
'path/to/fake/dir': {
'some-file.txt': 'file content here',
'empty-dir': {/** empty directory */}
},
'path/to/some.png': new Buffer([8, 6, 7, 5, 3, 0, 9]),
'some/other/path': {/** another empty directory */}
});
I like using rewire for stubbing out require(...) statements
Module Under test
module-a.js
var fs = require('fs')
function findFile(path, callback) {
fs.readdir(path, function(err, files) {
//Do something.
})
}
Test Code
module-a-test.js
var rewire = require('rewire')
var moduleA = rewire('./moduleA')
// stub out fs
var fsStub = {
readdir: function(path, callback) {
console.log('fs.readdir stub called')
callback(null, [])
}
}
moduleA.__set__('fs', fsStub)
// call moduleA which now has a fs stubbed out
moduleA()