Skip to content

Instantly share code, notes, and snippets.

@heyimalex
Created September 21, 2016 16:15
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save heyimalex/5b2f637c2a890c01f0876725cf1a848c to your computer and use it in GitHub Desktop.
Save heyimalex/5b2f637c2a890c01f0876725cf1a848c to your computer and use it in GitHub Desktop.
Using mock-fs with jest
// __tests__/example.js
jest.mock('fs');
it('should serve as a nice example', () => {
const fs = require('fs')
// fs can be set up at any point by calling __configureFs.
fs.__configureFs({
'/test': {
'a.foo': '----',
// mock-fs' other exports are also available on the fs object.
'b.bar': fs.__mockFile({
content: 'file content here',
ctime: new Date(1),
mtime: new Date(1)
}),
})
const results = fs.readdirSync('/test')
expect(results.length).toBe(2)
expect(results).toEqual(['a.foo', 'b.bar'])
})
// __mocks__/fs.js
const mockfs = require('mock-fs');
const container = {
__internalFs: null,
__configureFs: (conf) => {
container.__internalFs = mockfs.fs(conf);
},
__mockFile: mockfs.file,
__mockDirectory: mockfs.directory,
__mockSymlink: mockfs.symlink,
}
const proxyfs = new Proxy(container, {
get: function (target, property, receiver) {
if (target.hasOwnProperty(property)) {
return target[property];
} else {
if (target.__internalFs === null) {
target.__internalFs = mockfs.fs();
}
return target.__internalFs[property];
}
}
})
module.exports = proxyfs;
// mock-fs hooks the native fs on first require, so unfortunately just using
// the __mocks__ file isn't enough; jest will mock fs itself and stuff gets
// complicated. I'm actually not completely sure _what_ happens, but the end
// result is that you need to require mock fs before anything else or it
// doesn't work.
require('mock-fs')
{
"devDependencies": {
"jest": "^15.1.1",
"mock-fs": "^3.11.0",
},
"scripts": {
"test": "jest"
},
"jest": {
"setupFiles": ["<rootDir>/jestsetup.js"]
}
}
@cesalberca
Copy link

I think this can be made in a much more simpler manner. Here is the code for a custom function that saves and loads a file to disk:

import * as mock from 'mock-fs'
// This is a library that promisifies fs, you can use fs as well
import * as fs from 'mz/fs'
import * as fileHandler from './../../utils/fileHandler'

beforeEach(async () => {
  // Creates an in-memory file system 
  mock({
    '/test': {
      'note.md': 'hello world!'
    }
  })
})

afterEach(async () => {
  mock.restore()
})

it('saves a file given it\'s contents', async () => {
  expect.assertions(1)
  await fileHandler.saveFile('/test/note2.md', 'ciao world!')
  return fs.exists('/test/note.md')
  .then(exist => expect(exist).toBeTruthy())
})

it('loads a file from disk', async () => {
  expect.assertions(1)
  return fileHandler.loadFile('/test/note.md')
  .then(data => expect(data).toBe('hello world!'))
})

@digitalkaoz
Copy link

@cesalberca did you tested it with4.x from mock-fs i have the same problem like @heyimalex
it looks to complex to me, but your version wont work neither...

did you both find a better solution today?

@gaspaonrocks
Copy link

@digitalkaoz For what it's worth, @cesalberca's solution works exactly as expected. In my case I use sync access and it works like a charm.

Here are my dependencies :

"dependencies": {
    "jest": "^23.4.1",
    "mock-fs": "^4.5.0"
  }

NB : I create an in-memory mock beforeEach assertion, but I call manually mock.restore() in my test, since it needs to happen at different times (before file access to assert the Error thrown, after file access to assert the success).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment