Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS testing writeFile with mock-fs

For example, I have the following file:

spec/config/file-mock.js

var mock = require('mock-fs');
mock({
  'files': {
    'expense.csv': 'a;b;c;d\n1;2;3;4\n5;6;7;8'
  }
});

app/reader/reader.js

var fs = require('fs');
var reader = {
    read: function(path) {
        return fs.readFileSync(path, 'utf8');
    },
    write: function(path, object) {
        fs.writeFileSync(path, object);
    }
};
module.exports = reader;

app/reader/reader.spec.js

describe('reader.js test', function(){
    var reader = require('./reader.js');
    var mock = require('mock-fs');
    it('should return a simple string', function(){
        expect(reader.read('files/expense.csv')).toEqual('a;b;c;d\n1;2;3;4\n5;6;7;8');
    });
    it('should write a json object', function(){
        // WHAT TO DO?!
    });
});

The reader.read function is working fine with mock-fs.

But I'm trying to test the reader.write function and I didn't found anything in the documentation about the "write" functions. Anyone already solved this?

like image 300
Fabio Picheli Avatar asked Nov 23 '16 14:11

Fabio Picheli


People also ask

What is the difference between writeFileSync and writeFile?

The only difference between writeFile and writeFileSync is in catching and handling the errors; otherwise, all parameters mentioned are available in both functions.

Is FS writeFile async?

writeFile() is an asynchronous method for writing data in files of any type.

Is FS readFileSync?

readFileSync() method is an inbuilt application programming interface of fs module which is used to read the file and return its content. In fs. readFile() method, we can read a file in a non-blocking asynchronous way, but in fs. readFileSync() method, we can read files in a synchronous way, i.e. we are telling node.


1 Answers

As @Strech posted in comments you might try an expect on reader.read after calling reader.write to check that the content has been written to the fake file.

IMHO there is a better way to test this functionality out a bit more stick to unit test principles. We know that fs module works because is part of node core modules and it's tested there, so we can mock fs methods and instead check that those methods are being called with the expected parameters, for instance using Sinon:

const Reader = require('../reader.js');
const sinon = require('sinon');
const fs = require('fs');
const expect = require('expect.js');

describe('reader.js test', function () {

  let readFileSync;
  let writeFileSync;

  beforeEach(() => {
    readFileSync = sinon.stub(fs, 'readFileSync').returns({});
    writeFileSync = sinon.stub(fs, 'writeFileSync').returns({});
  });
  afterEach(() => {
    readFileSync.restore();
    writeFileSync.restore();
  });

  it('should return a simple string', () => {

    Reader.read('files/expense.csv');
    expect(readFileSync.calledOnceWith('files/expense.csv', 'utf8')).to.be(true);
  });

  it('should write a json object', () => {

    Reader.write('files/expense.csv', 'test');
    expect(writeFileSync.calledOnceWith('files/expense.csv', 'test')).to.be(true);
  });
});
like image 173
Borja Tur Avatar answered Oct 17 '22 04:10

Borja Tur